您的位置:首页 > 大数据 > 人工智能

【GDKOI2016】染色大战 Code&Details

2016-03-04 19:38 393 查看

Details

打起来很简单,但是打完会超时,才发现一些问题。

打了一个很短的方法。

每一层和下一层,都是min,max,min,max……这样的,但是我们把下一层要算的值去一个相反数,那我们就可以全部都取max。例如o=min(o,dfs(...)−p)o=min(o,dfs(...)-p)和o=max(o,p−dfs(...))o=max(o,p-dfs(...))是一样的。

设当前在i,j处填了一个1个贡献为k

因为我们会有一段连续的。所以在k=0时,要取的是o=max(−dfs(...),o)o=max(-dfs(...),o);否则要取的就是o=max(dfs(...)+k,o)o=max(dfs(...)+k,o)。因为当k=0的时候,下一层与上一层操作的人是不一样的,下层的人对当前来说贡献为负数;否则贡献就为正数。

还要记忆化,开始记忆化方法打错了。

用f[i]表示,当前二进制状况为i的最大博弈贡献值。如果f[i]已经有值了,那么就不继续往下做了。

Code

[code]#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<cmath>
#define fo(i,a,b) for(i=a;i<=b;i++)
const int maxn=100;
using namespace std;
int i,j,k,l,t,n,m,ans,tp;
int a[maxn][maxn],b[maxn][maxn];
int f[5000000];
int ci[maxn][maxn];
bool pan(int x,int y){return a[x][y]&&a[x+1][y]&&a[x][y+1]&&a[x+1][y+1];}
int de(int x,int y){
    return (x-1)*m+y;
}
int dfs(int x,int z){
    int i,j,k;
    if(f[z]!=tp)return f[z];
    bool dz=1;
    fo(i,1,n){
        fo(j,1,m){
            if(a[i][j]==0){
                dz=0;
                k=0;
                a[i][j]=1;
                if(pan(i,j))k+=b[i][j];if(pan(i-1,j))k+=b[i-1][j];
                if(pan(i-1,j-1))k+=b[i-1][j-1];if(pan(i,j-1))k+=b[i][j-1];
                int y=x;
                if(k==0)y=x^1; 
                if(k==0)f[z]=max(k-dfs(y,z+ci[i][j]),f[z]);else f[z]=max(f[z],k+dfs(y,z+ci[i][j]));
                a[i][j]=0;
            }
        }
    }   
    if(dz)f[z]=0;
    return f[z];
}
int main(){
    scanf("%d%d",&n,&m);
    int u=1;
    memset(f,128,sizeof(f));
    tp=f[0];
    fo(i,1,n){
        fo(j,1,m){
            scanf("%d",&a[i][j]);
            u=u*2;
            ci[i][j]=u;
        }
    }
    int up=0;
    fo(i,1,n) fo(j,1,m)if(a[i][j])up+=ci[i][j];
    fo(i,1,n-1){
        fo(j,1,m-1){
            scanf("%d",&b[i][j]);
        }
    }
    printf("%d\n",dfs(0,up)); 
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: