POJ 1321 棋盘问题
dp[n行][位压缩数][剩下k个棋子]
不用n行滚动数组也可。
更新与之前所有行不冲突的情况以及不放棋子情况,最后对dp[n][all][0]求和。
1 #include<stdio.h> 2 #include<string.h> 3 #include<stdlib.h> 4 int n, k; 5 const int maxn = 1 << 8 | 1; 6 int dp[10][maxn][10]; 7 char g[10][10]; 8 int main() 9 { 10 while(scanf("%d%d", &n, &k), n != -1 || k != -1) 11 { 12 memset(dp, 0, sizeof(dp)); 13 for(int i = 1; i <= n; i ++) 14 scanf("%s", g[i]); 15 int M = 1 << n; 16 dp[0][0][k] = 1; 17 for(int i = 1; i <= n; i ++) 18 { 19 for(int p = 0; p < M; p ++) 20 { 21 for(int j = 0; j < n; j ++) 22 { 23 if((~p & (1 << j)) && g[i][j] == '#') 24 { 25 for(int q = 1; q <= k; q ++) 26 dp[i][p | (1 << j)][q - 1] += dp[i - 1][p][q]; 27 } 28 } 29 for(int q = 0; q <= k; q ++) 30 dp[i][p][q] += dp[i - 1][p][q]; 31 } 32 } 33 int ans = 0; 34 for(int i = 0; i < M; i ++) 35 ans += dp[n][i][0]; 36 printf("%d\n", ans); 37 } 38 return 0; 39 }