1. 程式人生 > >[九省聯考2018]一雙木棋

[九省聯考2018]一雙木棋

tchar clu www 每一個 fprintf %d 一個 new con

[Luogu4363] [LOJ2471]

搜索做法 , 對每一個狀態hash存下答案

#include<cstdio>
#include<iostream>
#include<map>
#define debug(...) fprintf(stderr,__VA_ARGS__)
#define Debug(x) cout<<#x<<"="<<x<<endl
using namespace std;
typedef long long LL;
const int INF=1e9+7;
inline LL read(){
    register LL x=0,f=1;register char c=getchar();
    while(c<48||c>57){if(c=='-')f=-1;c=getchar();}
    while(c>=48&&c<=57)x=(x<<3)+(x<<1)+(c&15),c=getchar();
    return f*x;
}

const int N=11;
const int base=11;

int a[N][N],b[N][N],num[N];
int n,m;

namespace HashMap{
    map <LL,int> M;
    inline LL Hash(){
        LL res=0;
        for(int i=1;i<=n;i++) res=res*base+num[i];
        return res;
    }
    inline void unzip(LL sta){
        for(int i=n;i>=1;i--) num[i]=sta%base,sta/=base;
    }
    inline int nxtstep(){
        int res=0;
        for(int i=1;i<=n;i++) res+=num[i];
        return res&1;
    }
}using namespace HashMap;

inline int dfs(LL sta){
    if(M.count(sta)) return M[sta];
    unzip(sta);
    int type=nxtstep(),res=(!type)?-INF:INF;
    for(int i=1;i<=n;i++)
        if(num[i]<num[i-1]){
            num[i]++;
            LL nxt=Hash();//對每一個狀態hash存下答案
            if(!type) res=max(res,dfs(nxt)+a[i][num[i]]);//順著搜
            else res=min(res,dfs(nxt)-b[i][num[i]]);
            num[i]--;
        }
    return M[sta]=res;
}

int main(){
    n=read(),m=read();
    num[0]=m;
    for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) a[i][j]=read();
    for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) b[i][j]=read();

    for(int i=1;i<=n;i++) num[i]=m;
    M[Hash()]=0;//full

    printf("%d\n",dfs(0));
}

輪廓線做法

[九省聯考2018]一雙木棋