POJ 3254 Corn Fields [DP]

题意:略。

思路:第一次做状态压缩的dp。

在这里说一下状态压缩的原则。因为每一行只有最多12个格子,每个格子只有1(可放牛)和0(不可放牛)两种状态,这总共是2^12种状态,直接用一个int整型变量从0枚举到2^12 - 1。对于每一个数,将其转换成二进制,先判断格子为0时该数二进制对应位上是不是1,若是则该状态不可行。其次再判断该数相邻的两位有没有同时为1的情况,如果有,该状态也不可行。

递推公式就是:dp[i][k] = dp[j][k-1]。

其中dp[i][k]表示在牧场第k行状态为i时可行解的数量。它等于上一层所有可行状态的可行解数量之和。

在dp过程中,在判断该层的上一层某状态是否可行时,需要判断两层状态有没有上下相邻的位同为1的情况,如果有,则上一层的状态不可行,跳过。

此外在计算可行解数量和时别忘了取模。

 1 #include<stdio.h>

 2 #include<iostream>

 3 #include<string.h>

 4 #include<algorithm>

 5 #define pri 100000000

 6 using namespace std;

 7 int m, n;

 8 int farm[15][15];

 9 int dp[1<<13][15];

10 bool judge(int i,int pos)//判断状态i在牧场第pos行是否合法

11 {

12     int now = n;

13     int last = 0;

14     while (now)

15     {

16         int num = i % 2;

17         if (!farm[pos][now] && num || (last && num)) return 0;

18         last = num;

19         i /= 2;

20         now--;

21     }

22     return 1;

23 }

24 bool judge_state(int i,int j)//判断状态i和j能否放在牧场上下相邻的两行

25 {

26     int now = n;

27     while (now)

28     {

29         if ((i % 2) && (j % 2)) return 0;

30         i /= 2;

31         j /= 2;

32         now--;

33     }

34     return 1;

35 }

36 int getdp()

37 {

38     memset(dp, 0, sizeof(dp));

39     for (int i = 0; i < (1<<n); i++)//初始化第一行

40         if (judge(i, 1)) dp[i][1] = 1;

41     for (int i = 2; i <= m; i++)//枚举牧场剩下的每一行

42         for (int j = 0; j < (1<<n); j++) if (judge(j, i))//枚举该行可行的状态

43             for (int k = 0; k < (1<<n); k++) if (dp[k][i-1])//枚举上一行可行的状态

44                 if (judge_state(j, k))

45                 {

46                     dp[j][i] += dp[k][i-1];

47                     dp[j][i] %= pri;

48                 }

49     int res = 0;

50     for (int i = 0; i < (1<<n); i++)

51     {

52         res += dp[i][m];

53         res %= pri;

54     }

55     return res;

56 

57 }

58 int main()

59 {

60     scanf("%d%d", &m, &n);

61     for (int i = 1; i <= m; i++)

62         for (int j = 1; j <= n; j++)

63             scanf("%d", &farm[i][j]);

64     printf("%d", getdp());

65     return 0;

66 }

 

你可能感兴趣的:(Field)