题目点我点我点我
题目大意:简单不多说
思路:先全列出所有可行的状态,放炮兵就为1,不放就为0,这时先不考虑地形,把可行状态列出来后,再与地形匹配,山地H为1,平原p为0,这样两者以二进制匹配得数为0则匹配成功。
然后第i行(i>2)只由第i-1行的状态和第i-2行的状态决定,dp[i][j][k]代表第i行的状态为j,第i-1行状态为k,所以有状态转移方程 dp[i][j][k]=max(dp[i][j][k],dp[i-1][k][l]+soldier[j]),soldier[j]表示j状态下炮兵数量。
另外要初始化第一行第二行的状态,详情见代码。
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
#define maxn 60 //状态数,另用程序跑跑记录10列是有60种符合的状态
int state[maxn],soldier[maxn]; //state记录可行状态,soldier记录士兵数
int top,N,M; //top记录最多的可行状态数
int place[102],dp[102][maxn][maxn]; //place记录输入地形
char s[11];
void init() //初始化所有可行状态,1代表放士兵,0则无
{
top=0;
for(int i=0;i<1<<10;i++)
{
if(((i<<1)&i)||((i<<2)&i)) //左边两格是否有其他炮兵
continue;
int temp=i;
while(temp)
{
if(temp&1)soldier[top]++; //每一个1炮兵就多一个
temp>>=1;
}
state[top++]=i; //记录这个状态
}
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
init();
while(~scanf("%d%d",&N,&M))
{
int ans=0;
for(int i=1;i<=N;i++)
{
scanf("%s",s);
place[i]=0;
for(int j=0;j<M;j++)
{
place[i]<<=1;
if(s[j]=='H') //山地就二进制记为1
place[i]++;
}
}
memset(dp,0,sizeof(dp));
for(int i=1;i<=N;i++)
{
if(i==1) //初始化第一行
{
for(int j=0;j<top&&state[j]<(1<<M);j++)
{
if((state[j]&place[i])==0) //可行状态与地形匹配
dp[1][j][0]=soldier[j];
ans=max(ans,dp[1][j][0]);
}
}
else if(i==2) //初始化第二行
{
for(int j=0;j<top&&state[j]<(1<<M);j++)
{
if( (state[j]&place[i]) == 0 )
{
for(int k=0;k<top&&state[k]<(1<<M);k++)
{
if( ( (state[k]&place[i-1]) ==0 ) && ( (state[k]&state[j]) ==0))
//可行状态与地形匹配以及第i行可行状态与第i-1行可行状态匹配,下面也一样
dp[2][j][k]=dp[1][k][0]+soldier[j]; //这里是第二行,直接加,不用max函数
ans=max(ans,dp[2][j][k]);
}
}
}
}
else
{
for(int j=0;j<top&&state[j]<(1<<M);j++)
{
if( (state[j]&place[i]) ==0)
{
for(int k=0;k<top&&state[k]<(1<<M);k++)
{
if(( (state[k]&place[i-1]) ==0)&&( (state[k]&state[j]) ==0))
{
for(int l=0;l<top&&state[l]<(1<<M);l++)
{
if(( (state[l]&place[i-2] )==0)&&( (state[l]&state[j]) ==0)&&( (state[l]&state[k]) ==0))
{
dp[i][j][k]=max(dp[i][j][k],dp[i-1][k][l]+soldier[j]);
}
}
}
ans=max(ans,dp[i][j][k]);
}
}
}
}
}
printf("%d\n",ans);
}
return 0;
}