SGU 223 Little Kings
每行摆棋子状态位压缩,对能够相邻的行链表建图,dp[n行][状态1024][还剩下没放的棋子数k],最后把dp[n][all(合法)][0]相加。
1 #include<stdio.h> 2 #include<string.h> 3 #include<stdlib.h> 4 const int maxn = 1033; 5 int fst[1033], nex[maxn * maxn], v[maxn * maxn]; 6 int wnum; 7 void Add(int a, int b) 8 { 9 nex[wnum] = fst[a]; 10 fst[a] = wnum; 11 v[wnum] = b; 12 wnum ++; 13 } 14 15 bool OK(int a) 16 { 17 if((a & 1) && (a & 2)) return false; 18 int i; 19 for(i = 1; i < 10; i ++) 20 if((a >> i & 1) && ((a >> (i + 1) & 1) || (a >> (i - 1) & 1))) 21 return false; 22 if((a >> i & 1) && (a >> (i - 1) & 1)) 23 return false; 24 return true; 25 } 26 bool OK(int a, int b) 27 { 28 if((a & 1) && ((b & 1) || (b & 2))) 29 return false; 30 int i; 31 for(i = 1; i < 10; i ++) 32 { 33 if((a >> i & 1) && ((b >> (i - 1) & 1) || (b >> i & 1) || (b >> (i + 1) & 1))) 34 return false; 35 } 36 if((a >> i & 1) && ((b >> (i - 1) & 1) || (b >> i & 1))) 37 return false; 38 return true; 39 } 40 41 bool ok[maxn]; 42 bool ook[maxn][maxn]; 43 void Build() 44 { 45 for(int i = 0; i < maxn; i ++) ok[i] = OK(i); 46 for(int i = 0; i < maxn; i ++) 47 for(int j = 0; j < maxn; j ++) ook[i][j] = ok[i] && ok[j] && OK(i, j); 48 for(int i = maxn - 1; i >= 0; i --) 49 { 50 for(int j = maxn - 1; j >= 0; j --) 51 { 52 if(ok[i] && ok[j] && ook[i][j]) 53 Add(i, j); 54 } 55 } 56 } 57 int n, k; 58 __int64 dp[11][maxn][111]; 59 int COUNT(int x) 60 { 61 int cnt = 0; 62 while(x) cnt ++, x &= x - 1; 63 return cnt; 64 } 65 int main() 66 { 67 memset(fst, -1, sizeof(fst)); 68 wnum = 0; 69 Build(); 70 while(scanf("%d%d", &n, &k) != EOF) 71 { 72 memset(dp, 0, sizeof(dp)); 73 int M = 1 << n; 74 for(int i = 0; i < M; i ++) 75 if(COUNT(i) <= k) 76 dp[0][i][k - COUNT(i)] = ok[i]; 77 for(int i = 1; i < n; i ++) 78 { 79 for(int j = 0; j < M; j ++) 80 { 81 for(int u = fst[j]; u != -1 && v[u] < M; u = nex[u]) 82 { 83 for(int K = COUNT(v[u]); K <= k; K ++) 84 dp[i][v[u]][K - COUNT(v[u])] += dp[i - 1][j][K]; 85 } 86 } 87 } 88 __int64 ans = 0; 89 for(int i = 0; i < M; i ++) 90 ans += dp[n - 1][i][0]; 91 printf("%I64d\n", ans); 92 } 93 return 0; 94 }