Chinaunix首页 | 论坛 | 博客
  • 博客访问: 134913
  • 博文数量: 34
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 700
  • 用 户 组: 普通用户
  • 注册时间: 2014-11-12 16:52
文章分类

全部博文(34)

文章存档

2015年(13)

2014年(21)

我的朋友

分类: C/C++

2015-01-30 14:38:02

经典的状态压缩dp,有几个点要注意

1)必须用三维的状态才能合理的进行状态的转移,用二维的状态约束性不够

2)初始化是必须要同时初始化前两行的所有状态

3)注意位运算的使用。


代码如下:


[html] view plaincopy在CODE上查看代码片派生到我的代码片
  1. #include<iostream>  
  2. #include<cstdio>  
  3. #include<cstring>  
  4. using namespace std;  
  5.   
  6. int total[1000],cur[110];  
  7. int dp[110][200][200];  
  8. int top,n,m;  
  9. int c[100];  
  10.   
  11. int ok(int x,int y)  
  12. {  
  13.     if(x&y)  
  14.         return 0;  
  15.     return 1;  
  16. }  
  17.   
  18. int cnt(int x)  
  19. {  
  20.     int d=0;  
  21.     while(x>0)  
  22.     {  
  23.         if(x&1)  
  24.           d++;  
  25.         x=x>>1;  
  26.     }  
  27.     return d;  
  28. }  
  29.   
  30. void Allstate()  
  31. {  
  32.     top=1;  
  33.     int k=(1<<m);  
  34.     for(int i=0;i<k;i++)  
  35.     {  
  36.         if(((i<<1)&i)||((i<<2)&i))  
  37.             continue;  
  38.         total[top++]=i;  
  39.     }  
  40. }  
  41.   
  42. int main()  
  43. {  
  44.     while(scanf("%d%d",&n,&m)!=EOF)  
  45.     {  
  46.          Allstate();  
  47.          char str[20];  
  48.          memset(cur,0,sizeof(cur));  
  49.          for(int i=1;i<=n;i++)  
  50.          {  
  51.              scanf("%s",str+1);  
  52.              int x=0;  
  53.              for(int j=1;j<=m;j++)  
  54.              {  
  55.                  if(str[j]=='P')  
  56.                    x=x*2+1;  
  57.                  else  
  58.                    x=x*2;  
  59.              }  
  60.              cur[i]=~x;  
  61.          }  
  62.          memset(dp,0,sizeof(dp));  
  63.          for(int i=1;i<top;i++)  
  64.              c[i]=cnt(total[i]);  
  65.          for(int i=1;i<top;i++)  
  66.          {  
  67.              if(ok(total[i],cur[1]))  
  68.                   dp[1][i][0]=c[i];  
  69.          }  
  70.          for(int i=1;i<top;i++)  
  71.          {  
  72.              if(ok(total[i],cur[2])==0)  
  73.                  continue;  
  74.              for(int j=0;j<top;j++)  
  75.              {  
  76.                  if(ok(total[j],cur[1])==0)  
  77.                      continue;  
  78.                  if(ok(total[i],total[j])==0)  
  79.                      continue;  
  80.                  dp[2][i][j]=max(dp[2][i][j],dp[1][j][0]+c[i]);  
  81.              }  
  82.          }  
  83.          for(int i=3;i<=n;i++)  
  84.            for(int j=1;j<top;j++)  
  85.            {  
  86.                if(ok(cur[i],total[j])==0)  
  87.                   continue;  
  88.                for(int d1=0;d1<top;d1++)  
  89.                {  
  90.                    if(ok(cur[i-1],total[d1])==0)  
  91.                       continue;  
  92.                    if(ok(total[d1],total[j])==0)  
  93.                       continue;  
  94.                    for(int d2=0;d2<top;d2++)  
  95.                    {  
  96.                        if(ok(cur[i-2],total[d2])==0)  
  97.                           continue;  
  98.                        if(ok(total[d2],total[j])==0)  
  99.                           continue;  
  100.                        if(ok(total[d2],total[d1])==0)  
  101.                           continue;  
  102.                         dp[i][j][d1]=max(dp[i][j][d1],dp[i-1][d1][d2]+c[j]);  
  103.                    }  
  104.                }  
  105.            }  
  106.          int ans=0;  
  107.          for(int i=1;i<top;i++)  
  108.            for(int j=0;j<top;j++)  
  109.               ans=max(ans,dp[n][i][j]);  
  110.          printf("%d\n",ans);  
  111.     }  
  112.   return 0;  
  113. }  
  114. 文章转自
阅读(560) | 评论(0) | 转发(0) |
0

上一篇: Android发送多个notification

下一篇:Ruby入门

给主人留下些什么吧!~~