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 }

 

posted @ 2013-09-24 21:24  CSGrandeur  阅读(199)  评论(0编辑  收藏  举报