hdu 2167(状压dp)

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

思路:经典的状压dp题,前后,上下,对角8个位置不能取,状态压缩枚举即可所有情况,递推关系是为dp[i][j]=max(dp[i][j],dp[i-1][k]+sum[i][j]),具体的含义见code:

 1 #include<iostream>

 2 #include<cstdio>

 3 #include<cstring>

 4 #include<algorithm>

 5 using namespace std;

 6 

 7 int s[1<<16];

 8 int sum[16][1<<16];

 9 int dp[16][1<<16];

10 int map[16][16];

11 int n,m,ans;

12 

13 void Solve()

14 {

15     m=0;

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

17         if((i&(i<<1))==0)s[m++]=i;//所有合法的状态

18     }

19     memset(sum,0,sizeof(sum));

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

21     for(int i=0;i<n;i++){

22         for(int j=0;j<m;j++){

23             for(int k=0;k<n;k++){

24                 if(s[j]&(1<<k))sum[i][j]+=map[i][k];//sum又来保存每一行的合法状态下的所有数的和

25             }

26         }

27     }

28     for(int i=0;i<m;i++)dp[0][i]=sum[0][i];

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

30         for(int j=0;j<m;j++){

31             for(int k=0;k<m;k++){ //上一行状态

32                 if(s[j]&s[k])continue;

33                 if(s[j]&(s[k]>>1))continue;

34                 if(s[j]&(s[k]<<1))continue;

35                 dp[i][j]=max(dp[i][j],dp[i-1][k]+sum[i][j]);

36             }

37         }

38     }

39     ans=0;

40     for(int i=0;i<m;i++){

41         ans=max(ans,dp[n-1][i]);

42     }

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

44 }

45                 

46 

47 int main()

48 {

49     char str[111];

50     while(gets(str)){

51         int len=strlen(str);

52          n=0;

53         for(int i=0;i<len;i+=3){

54             map[0][n++]=(str[i]-'0')*10+(str[i+1]-'0');

55         }

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

57             int nn=0;

58             gets(str);

59             for(int j=0;j<len;j+=3){

60                 map[i][nn++]=(str[j]-'0')*10+(str[j+1]-'0');

61             }

62         }

63         Solve();

64         getchar();

65     }

66     return 0;

67 }

68 

69             
View Code

 

你可能感兴趣的:(HDU)