hdu 4539(状压dp)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4539

思路:跟poj1185简直就是如出一辙!

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 
 7 int row[111];
 8 int dp[111][222][222];
 9 int s[1<<12];
10 int num[1<<12];
11 int n,m,state,ans,x;
12 
13 int Get_Num(int x)
14 {
15     int cnt=0;
16     while(x>0){
17         cnt++;
18         x=x&(x-1);
19     }
20     return cnt;
21 }
22 
23 int main()
24 {
25     while(~scanf("%d%d",&n,&m)){
26         memset(row,0,sizeof(row));
27         memset(dp,0,sizeof(dp));
28         for(int i=0;i<n;i++){
29             for(int j=0;j<m;j++){
30                 scanf("%d",&x);
31                 if(!x)row[i]=(row[i]<<1)|1;
32                 else row[i]<<=1;
33             }
34         }
35         state=0;
36         for(int i=0;i<(1<<m);i++){
37             if(i&(i<<2))continue;
38             s[state]=i;
39             num[state++]=Get_Num(i);
40         }
41         for(int i=0;i<state;i++){
42             if(s[i]&row[0])continue;
43             dp[0][i][0]=num[i];
44         }
45         for(int i=1;i<n;i++){
46             for(int j=0;j<state;j++){
47                 if(s[j]&row[i])continue;
48                 for(int k=0;k<state;k++){  //i-1行信息
49                     if((s[j]&(s[k]>>1))||(s[j]&(s[k]<<1)))continue;//曼哈顿距离为2冲突
50                     for(int l=0;l<state;l++){  //i-2行信息
51                         if(s[j]&s[l])continue;
52                         if((s[k]&(s[l]>>1))||(s[k]&(s[l]<<1)))continue;//曼哈顿距离为2冲突
53                         dp[i][j][k]=max(dp[i][j][k],dp[i-1][k][l]+num[j]);
54                     }
55                 }
56             }
57         }
58         ans=0;
59         for(int i=0;i<state;i++){
60             for(int j=0;j<state;j++){
61                 ans=max(ans,dp[n-1][i][j]);
62             }
63         }
64         printf("%d
",ans);
65     }
66     return 0;
67 }
View Code
原文地址:https://www.cnblogs.com/wally/p/3292462.html