POJ 1185 状压DP

legal[] 保存所有在当前行可显示的状态,由dfs得到,len[]保存legal[]对应下标状态中的 1 的个数 , 也就是放置炮台的个数

state[i] 表示第 i 行这块区域的土地情况,H表示 1 ,P表示 0

那么每次加入一个legal状态  都要符合 !(legal[i] & state[k])

 

 1 #include <cstdio>

 2 #include <cstring>

 3 #include <iostream>

 4 using namespace std;

 5 int dp[105][80][80],vis[12],state[105],legal[80],len[80];

 6 int cnt,n,m;

 7 

 8 void dfs(int u , int _state , int l)

 9 {

10     if(u > m){

11         legal[++cnt] = _state;

12         len[cnt] = l;

13         return;

14     }

15     int flag = 1;

16     if(u>1){

17         if(vis[u-1]) flag=0;

18     }

19     if(u>2){

20        if(vis[u-2]) flag=0;

21     }

22     if(flag){

23         vis[u] = 1;

24         dfs(u+1 , _state<<1|1 , l+1);

25         vis[u] = 0;

26     }

27     dfs(u+1 , _state<<1 , l);

28 }

29 

30 void DP()

31 {

32     for(int k=1;k<=n;k++){

33         for(int i=1;i<=cnt;i++){

34             for(int j=1;j<=cnt;j++){

35                 if(k == 1 && !(state[k] & legal[i])){

36                     dp[k][j][i] = len[i];

37                 }

38                 for(int t=1;t<=cnt;t

39                 ++){

40                     if(!(state[k] & legal[i]) && !(legal[i] & legal[j]) && !(legal[i] & legal[t]) && !(legal[t] & legal[j])){

41                         dp[k][j][i] = max(dp[k][j][i] , dp[k-1][t][j] + len[i]);

42                     }

43                 }

44             }

45         }

46     }

47 }

48 

49 int main()

50 {

51     //freopen("POJ1185.test","rb",stdin);

52     char c;

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

54         for(int i=1;i<=n;i++){

55             state[i] = 0;

56             for(int j=1 ; j<=m ; j++){

57                 cin>>c;

58                 if(c == 'H') state[i] = state[i]<<1|1;

59                 else state[i] = state[i]<<1;

60             }

61         }

62         cnt=0;

63         memset(vis,0,sizeof(vis));

64         dfs(1,0,0);

65 

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

67         DP();

68 

69         int ans=0;

70         for(int i=1;i<=cnt;i++){

71             for(int j=1;j<=cnt;j++){

72                 ans = max(dp[n][i][j] , ans);

73             }

74         }

75         cout<<ans<<endl;

76     }

77 

78     return 0;

79 }

 

你可能感兴趣的:(poj)