poj1185

来源:互联网 发布:淘宝不能复制宝贝 编辑:程序博客网 时间:2024/05/22 08:14

这道题目和poj3254属于类型题,思想和方法上都类似,首先,自己做麻烦的第一点在于 a&b 两个十进制的数本身就可以判断两列是否有炮兵对打,而不用像我一开始想象的把十进制转成二进制,再用二进制进行判断,这个已经帮你弄好了。
第二点,本身状态也没有那么多。最多是1024个,再加上用if((i&i<<1)||(i&i<<2)) (这个判断简直了)之后就剩了大概六十个左右好像是。所以将这些合理的状态记录下来,这样的思路就能够想到了。
第三点,判断状态 哪一行是属于第几个状态,这点也很好。
剩下的就是状态dp自己的事了,什么这一行的值只和前两行有关什么的。

#include <iostream>  #include <vector>  #include <string>  #include <cstring>  #include <algorithm>  #include <cmath>  #pragma warning(disable:4996)  using namespace std;  int hang[110];//hang[i]表示第i行的初始状态  int state[80];//  int solider[80];  int dp[110][80][80];  int row,col,i,j,k,h,he;  char pb_state[15];  int main()  {      cin>>row>>col;      memset(hang,0,sizeof(hang));      memset(dp,0,sizeof(dp));      memset(solider,0,sizeof(solider));      memset(state,0,sizeof(state));      for(i=1;i<=row;i++)      {          cin>>pb_state;          for(j=0; j<col; j++)              if(pb_state[j]=='H') hang[i]+=1<<j;       }      he=1;      for(i=0;i<(1<<col);i++)      {          if((i&i<<1)||(i&i<<2)) continue;          state[he]=i;          int temp=i,num=0;          while(temp)          {              num += temp&1;              temp=temp>>1;          }          solider[he]=num;          he++;      }      for(i=1;i<he;i++)      {          if(state[i]&hang[1])continue;          dp[1][i][0]= solider[i];      }      for(i=1;i<he;i++)      {          if(state[i]&hang[2])continue;          for(j=1;j<he;j++)          {              if(state[i]&state[j])continue;              if(state[j]&hang[1]) continue;              dp[2][i][j]=max(dp[2][i][j],dp[1][j][0]+solider[i]);          }      }      for(h=3;h<=row;h++)      {          for(i=1;i<he;i++)//          {              if(state[i]&hang[h])continue;              for(j=1;j<he;j++)              {                  if(state[j]&hang[h-1])continue;                  if(state[j]&state[i])continue;                  for(k=1;k<he;k++)                  {                      if(state[k]&hang[h-2])continue;                      if(state[k]&state[i])continue;                      if(state[k]&state[j])continue;                      dp[h][i][j]=max(dp[h][i][j],dp[h-1][j][k]+solider[i]);                  }              }          }      }      int ans=0;      for(i=1;i<he;i++)          for(j=0;j<he;j++)//!!!注意啊,这里一定是从0开始的,因为之前设置好的就是0啊。。。。。。。。。。。。。。。。。。              ans=max(ans,dp[row][i][j]);      cout<<ans<<endl;      //system("pause");      return 0;  }  
0 0