bzoj5248: [2018多省省队联测]一双木棋

题目链接

bzoj5248: [2018多省省队联测]一双木棋

题解

现场居然没写出来.....真是脑残限制想象力
棋子的摆放形态是递增的,状态数并不多,三十多万吧
对抗搜索,map记忆化一下状态。完了
当时没敢想.....唉
hash的时候卡了以下base.....10 or 11以下会T,好玄学啊

代码

#include<map>
#include<cstdio>
#include<cstring>
#include<algorithm>
const int maxn = 13;
#define LL long long
int n,m;
int a[maxn][maxn],b[maxn][maxn]; 
int sta[maxn]; 
int base = 13;
std::map<LL,int>mp;
inline LL hash() { 
    LL ret = 0;
    for(int i = 1;i <= n;++ i) ret = ret * base + sta[i]; 
    return ret;
} 
void get_s(LL tmp) {
    for(int i = n;i;i --) sta[i] = tmp % base,tmp /=  base; 
    //puts("") ;
}
inline bool get_NS () {
    int ret = 0; 
    for(int i = 1;i <= n;++ i) ret += sta[i]; 
    return ret & 1; 
}
inline int dfs(LL state) {
    if(mp.find(state) != mp.end()) return mp[state]; 
    get_s(state); 
    bool type = get_NS() ; 
    int ret = type ? 0x3f3f3f3f : -0x3f3f3f3f; 
    for(int i = 1;i <= n;++ i) 
        if(sta[i - 1] > sta[i]) { 
            ++ sta[i];
            LL Next = hash(); 
            if(!type) ret = std::max(ret,dfs(Next) + a[i][sta[i]]); 
            else  ret = std::min(ret,dfs(Next) - b[i][sta[i]]); 
            -- sta[i]; 
        } 
    mp[state] = ret; 
    //printf("%d\n",ret);
    return ret; 
}
int main() {
    scanf("%d%d",&n,&m); 
    for(int i = 1;i <= n;++ i) 
        for(int j = 1;j <= m;++ j) 
            scanf("%d",&a[i][j]);   
    for(int i = 1;i <= n;++ i)  
        for(int j = 1;j <= m;++ j)  
            scanf("%d",&b[i][j]); 
    sta[0] = m;
    for(int i = 1;i <= n;++ i) sta[i] = m;
    mp[hash()] = 0;
    dfs(0); 
    //for(int i = 1;i <= 10000*n;++ i) {
        //printf("%d\n",mp[i]);
    //}
    printf("%d\n",mp[0]); 
    return 0;
}
posted @ 2018-04-29 19:34  zzzzx  阅读(168)  评论(3编辑  收藏  举报