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\n",ans);

65     }

66     return 0;

67 }
View Code

 

你可能感兴趣的:(HDU)