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;i y)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; }