[状压dp]POJ1185 炮兵阵地

中文题 题意不再赘述

 

[状压dp]POJ1185 炮兵阵地

对于中间这个“P” 根据dp的无后效性 我们只需考虑前面的

就变成了 只需考虑:

[状压dp]POJ1185 炮兵阵地

也就是状压前两行

 

具体与HDOJ的4539类似: 看HDOJ 4539

仅仅是共存状态的判断不同

 

[状压dp]POJ1185 炮兵阵地
 1 //#include <bits/stdc++.h>

 2 #include <cstdio>

 3 #include <cstring>

 4 #include <iostream>

 5 #include <algorithm>

 6 using namespace std;

 7 typedef long long LL;

 8 

 9 int dp[2][1050][1050], mp[105][105];

10 int pos[1050], d;

11 int main()

12 {

13     int d=0;

14     for(int i=0;i<(1<<10);i++)

15         if(!(i&(i<<2)) && !(i&(i<<1)))

16             pos[d++]=i;// 预处理 一行 符合条件的

17     int n, m;

18     while(~scanf("%d%d", &n, &m))

19     {

20         int ans=0;

21         memset(mp, 0, sizeof(mp));

22         for(int i=1;i<=n;i++)

23             for(int j=0;j<m;j++)

24             {

25                 char c;

26                 cin>>c;

27                 mp[i][j]=(c=='P');

28             }

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

30         for(int i=1;i<=n;i++)//枚举n行

31             for(int j=0;j<d && pos[j]<(1<<m);j++)

32             {

33                 int sum=0;

34                 for(int k=0;k<m;k++)//对于当前(i,k位置)该行(前面k格)是否满足

35                     if(pos[j]&1<<k)

36                         sum+=mp[i][k];

37                 for(int k=0;k<d && pos[k]<(1<<m);k++) // 枚举i-1行的状态 看能否与第i行共存

38                     if(!(pos[j]&pos[k]))

39                     {

40                         int tmp=0;

41                         for(int l=0;l<d && pos[l]<(1<<m);l++)  // 枚举i-2行的状态 看能否与第i行、第i-1行共存

42                             if(!(pos[j]&pos[l]))

43                                 tmp=max(tmp, dp[1-i&1][k][l]);

44                         dp[i&1][j][k]=tmp+sum;

45                         ans=max(ans, dp[i&1][j][k]);

46                     }

47             }

48         printf("%d\n", ans);

49     }

50     return 0;

51 }
POJ 1185

 

你可能感兴趣的:(poj)