poj1185-状态压缩DP

状态压缩学习论文:TJU 周伟的《状态压缩》

http://wenku.baidu.com/view/070924ec102de2bd96058839.html

 

http://poj.org/problem?id=1185第一个状态压缩DP,

 

留代码以后好看:

  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<math.h>
  4 #define N 101
  5 #define M 11
  6 #define S 66
  7 #define MAX(a,b) a>b?a:b
  8 
  9 int state[N][S];
 10 char map[M];
 11 int dp[2][S][S];
 12 int count[N][S];
 13 int gra;
 14 int n,m,s;
 15 int dfs(int i){
 16     int total = 1<<m;
 17     int item;
 18     int k,j;
 19     for (k= 1,j=0;j<total;j++){
 20         if ((j&gra)==0 && ((j>>2)&j)==0 && ((j>>1)&j)==0){
 21             state[i][k]=j;
 22             item = j;
 23             while (item){
 24                 if (item%2)
 25                     count[i][k]++;
 26                 item>>=1;
 27             }
 28             k++;
 29         }
 30 
 31     }
 32     count[i][0]=k;
 33 return 0;
 34 }
 35 
 36 
 37 int main()
 38 {
 39     int max;
 40 
 41     while (~scanf("%d%d",&n,&m)){
 42         memset(state,0,sizeof(state));
 43         //state[i][j] 表示第i行的放置方案为j
 44         //count[i][0]表示第i行可以放置的方案数
 45         //count[i][j] 表示第i行放置j时,j的二进制表示有多少个1
 46         memset(count,0,sizeof(count));
 47         memset(dp,0,sizeof(dp));
 48         for (int i=0;i<n;i++){
 49             scanf("%s",map);
 50             for (int j = gra=0;j<m;j++){
 51                 gra=gra*2+(map[j]=='P'?0:1);
 52             }
 53         //gra 表示当前行P的状态
 54 
 55             dfs(i);
 56         //搜索当前行的可能放置的状态state
 57         }
 58 
 59         //初始化第一行
 60         for (int i=1;i<count[0][0];i++){
 61             for (int j=1;j<S;j++){
 62                 dp[0][i][j]=count[0][i];
 63             }
 64         }
 65         //初始化第二行
 66         for (int i=1;i<count[1][0];i++){
 67             for (int j=1;j<count[0][0];j++){
 68                 if ((state[0][j] & state[1][i])==0)
 69                     dp[1][i][j]=count[0][j]+count[1][i];
 70             }
 71         }
 72 
 73 
 74 
 75         if (n>2){
 76             for (int i=2;i<n;i++){
 77                 for (int j=1;j<count[i][0];j++){
 78                     for (int k=1;k<count[i-1][0];k++){
 79                         max = 0;
 80                         if ((state[i][j] &state[i-1][k])==0){
 81                             for (int l = 1;l<count[i-2][0];l++){
 82                                 if((state[i][j]&state[i-2][l])==0 && (state[i-1][k]&state[i-2][l])==0){
 83                                     max = MAX(dp[(i-1)&1][k][l]+count[i][j],max);
 84                                 }
 85                             }
 86                         }
 87                         dp[i&1][j][k] = max;
 88                     }
 89                 }
 90             }
 91         }
 92         max= 0;
 93         for (int i=1;i<count[n-1][0];i++){
 94             for (int j=1;j<S;j++){
 95                 max = MAX(max,dp[(n-1)&1][i][j]);
 96             }
 97         }
 98         printf("%d\n",max);
 99     }
100     return 0;
101 }
POJ1185

 

转载于:https://www.cnblogs.com/wangsouc/articles/3218970.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值