Problem Description There is a 3 by 3 grid and each vertex is assigned a number.



1 15 1 2 1 5 2 6 5 9 6 10 9 10 5 6 2 3 3 7 7 11 10 11 3 4 6 7 7 8 4 8
Case #1: Tom200 Hint In case 1, Tom200 gets two points when she add edge 5 -> 6, two points in edge 6 -> 7, one point in 4 -> 8.
/**
hdu4753 狀態壓縮dp博弈(記憶化搜索寫法)
題目大意:為一個3*3的棋盤連邊(如圖所示)加上當前邊後多了幾個格子四條邊都被填上了,就得幾分,現在tom和jerry交替填邊,總是tom先,
現在已經填了n條邊了,問剩下的邊二者都采取最優的策略,誰會贏
解題思路:由於未知的邊最多只有12條,我們可以采取狀態壓縮,用搜索的方式寫
注意:不可以直接壓24位,會爆內存的
*/
#include
#include
#include
#include
using namespace std;
int mp[24][24];///給每條邊進行編號
int vis[25];///標記是否已經訪問過該邊
int dp[(1<<13)+3],cnt,x[25];
int tom,jerry,n;
int circle[9][4]={///對應的9個格子各自的四條邊
1,4,5,8,
2,5,6,9,
3,6,7,10,
8,11,12,15,
9,12,13,16,
10,13,14,17,
15,18,19,22,
16,19,20,23,
17,20,21,24
};
void init()
{
memset(mp,0,sizeof(mp));
mp[1][2]=1,mp[2][3]=2,mp[3][4]=3;
mp[1][5]=4,mp[2][6]=5,mp[3][7]=6,mp[4][8]=7;
mp[5][6]=8,mp[6][7]=9,mp[7][8]=10;
mp[5][9]=11,mp[6][10]=12,mp[7][11]=13,mp[8][12]=14;
mp[9][10]=15,mp[10][11]=16,mp[11][12]=17;
mp[9][13]=18,mp[10][14]=19,mp[11][15]=20,mp[12][16]=21;
mp[13][14]=22,mp[14][15]=23,mp[15][16]=24;
}
int judge()
{
int sum=0;
for(int i=0;i<9;i++)
{
if(vis[circle[i][0]]&&vis[circle[i][1]]&&vis[circle[i][2]]&&vis[circle[i][3]])
sum++;
}
return sum;
}
int ok(int ste,int k)
{
int vv[25];
memset(vv,0,sizeof(vv));
for(int i=0;i<=cnt;i++)
{
if(ste&(1<maxx)
maxx=k-sum;
}
}
return dp[ste]=maxx;
}
int main()
{
int T,tt=0;
scanf(%d,&T);
init();
while(T--)
{
memset(vis,0,sizeof(vis));
scanf(%d,&n);
tom=0,jerry=0;
int s=0,ste=0;
for(int i=0;iy)swap(x,y);
vis[mp[x][y]]=1;
int s1=judge();
if(i&1)
{
jerry+=(s1-s);
}
else
{
tom+=(s1-s);
}
s=s1;
/// printf((%d %d)
,tom,jerry);
}
cnt=-1;
for(int i=1;i<=24;i++)
{
if(!vis[i]) x[++cnt]=i;
}
s=9-judge();
memset(dp,-1,sizeof(dp));
int num=dfs(0,s);
printf(Case #%d: ,++tt);
if((n&1)==0)
{
if(tom+num>jerry+s-num)
printf(Tom200
);
else
printf(Jerry404
);
}
else
{
if(tom+s-num>jerry+num)
printf(Tom200
);
else
printf(Jerry404
);
}
}
return 0;
}