POJ 1185

来源:互联网 发布:ui平面设计软件 编辑:程序博客网 时间:2024/05/16 05:07

这题的关键在于当前行的状态,怎么与上一行的状态进行匹配。

看到一个大神的解法,是用数组的下去匹配的;好6;

先说一下为什么可以这样做:(一行的,不包括二面二行的为方案,一行的包括二行的为状态)

一行的状态包括上面二行,然而这一行的状态只要保存这一行和上一行的方案下标,这时可以作为保存数量的下标的位置。

比如,这一行的是i方案,上一行的是j方案,那么以数组i,j为下标的二维数组存下当前方案的数量加上上一组对应的数组中的j,t 下标的数量。

上一行是jt,这一行是i,j;这是以对应的,是变化来的;只要模拟走一篇就懂了;


#include <iostream>#include <cstring>using namespace std;const int M=10,N=101;int n,m;int now[65],last[65],lastlast[65];int nowsize,lastsize,lastlastsize;int num[65];int temp[N][N],dp[N][N];char Map[N][M];int maze[N];void initAloneState(int local){int i,j,k,temp;for(i=0; i<m; ++i){if( (maze[local]&(1<<i)) ){continue;}now[++nowsize] = (1<<i);num[nowsize] = 1;}for(i = 0; i < m-3; ++i){for(j = i+3; j < m; ++j){if((maze[local]&(1<<i)) || (maze[local]&(1<<j))){continue;}now[++nowsize] = (1<<i) + (1<<j);num[nowsize] = 2;}}for(i = 0; i < m-6; ++i){for(j = i+3; j < m-3; ++j){for(k = j+3; k < m; ++k){if((maze[local]&(1<<i)) || (maze[local]&(1<<j)) || (maze[local]&(1<<k))){continue;}now[++nowsize] = (1<<i) + (1<<j) + (1<<k);num[nowsize] = 3;}}}if(m==10 && !(585&maze[local])){now[++nowsize] = 585;num[nowsize] = 4;}//cout<<endl;//int count = 0;//for(i = 0; i <= nowsize; ++i){//if(num[i] == 4){//printf("%d %d\n",num[i],now[i]);//count++;//}//}//printf("count = %d\n",count);}void DP(){int i,j,k,t;now[0] = 0;for(k=0; k<n; ++k){memset(now, 0, sizeof(int)*60);nowsize=0;initAloneState(k);for(i=0;i<=nowsize;++i)for(int j=0;j<=lastsize;++j)dp[i][j]=0;          for(i=0;i<=nowsize;++i){//本行选择第几个方案               for(j=0;j<=lastsize;++j){//上一行选择第几个方案                   for(t=0;t<=lastlastsize;++t){//上上行选择第几个方案                       if( (now[i] & last[j]) )continue;//与上一行j方案不能共存                      if(now[i] & lastlast[t])continue;//与上上行t方案不能共存                      if(dp[i][j]<temp[j][t]+num[i]){dp[i][j]=temp[j][t]+num[i];                                     }                }              }          }                       for(int i=0;i<=nowsize;++i)for(int j=0;j<=lastsize;++j)temp[i][j]=dp[i][j];          for(int i=0;i<=lastsize;++i)lastlast[i]=last[i];lastlastsize=lastsize;          for(int i=0;i<=nowsize;++i)last[i]=now[i];lastsize=nowsize;  }}void initMaze(){char str[10],ch;for(int i=0; i<n; ++i){scanf("%s",str);for(int j=0; j<m; ++j){ch = str[j];if(ch == 'H'){maze[i] += (1<<j);}} }}int main(){memset(maze, 0, sizeof(int)*N);scanf("%d %d",&n,&m);initMaze();last[0]=lastlast[0]=temp[0][0]=0;      lastsize=lastlastsize=0;DP();int sum=0;      for(int i=0;i<=lastsize;++i){         for(int j=0;j<=lastlastsize;++j){              if(temp[i][j]>sum)sum=temp[i][j];                  }            }      printf("%d\n",sum);  return 0;}


原创粉丝点击