[GDKOI2016] Day2 染色大战 记忆化搜索

来源:互联网 发布:淘宝账号不能手机登陆 编辑:程序博客网 时间:2024/04/27 16:12

出题人讲这题的时候扯到了模拟退火,遗传算法,alphabeta剪枝等等
然而这题一个记忆化搜索就能跑过去

#include <iostream>#include <cstdio>#define INF (1<<30)#define N 22using namespace std;int n,m,tp,e[N][N],map[N][N],v[N][N];int vis[2][1<<N];const int fx[] = {0,1,0,-1};const int fy[] = {1,0,-1,0};inline void ut(int &x,int y) { x = max(x,y); }inline void check(int x,int y,int &c) {    if (map[x][y] && map[x+1][y] && map[x][y+1] && map[x+1][y+1]) c+=v[x][y];}int dfs(int x,int mask){    if (mask == tp) return 0;    if (vis[x][mask]) return vis[x][mask];    int ret = -INF;    for (int i=1;i<=n;i++)        for (int j=1;j<=m;j++) if (!map[i][j]){            map[i][j] = 1;            int val = 0;            check(i-1,j-1,val); check(i-1,j,val);            check(i,j-1,val); check(i,j,val);            if (val)                 val += dfs(x,mask+e[i][j]);            else                val -= dfs(x^1,mask+e[i][j]);            ut(ret,val);            map[i][j] = 0;              }    vis[x][mask] = ret;    return ret;}int main() {    scanf("%d%d",&n,&m);    for (int i=1;i<=n;i++)        for (int j=1;j<=m;j++)             e[i][j] = 1<<( (i-1)*m+j-1 );    for (int i=1;i<=n;i++)        for (int j=1;j<=m;j++) {            scanf("%d",&map[i][j]);            if (!map[i][j]) tp += e[i][j];        }    for (int i=1;i<=n-1;i++)        for (int j=1;j<=m-1;j++) scanf("%d",&v[i][j]);    //1先手 0后手     int ans = dfs(1,0);    printf("%d\n",ans);    return 0;}
0 0
原创粉丝点击