这题的关键在于当前行的状态,怎么与上一行的状态进行匹配。
看到一个大神的解法,是用数组的下去匹配的;好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;
}