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 }

 

你可能感兴趣的:(poj)