poj 1185

来源:互联网 发布:dialog数据库 专利 编辑:程序博客网 时间:2024/05/01 19:52

这题我纠结了一个晚上,一直不知道为什么simple过不了,思路很明确,没理由会错掉,直到今天早上,我把所有的变量打出来看看,发现了一个错误,在弄状态的时候,打多个等号,导致多了一种不应该存在的状态,罪过啊,潜意识竟然都默认那是对的。后来改过来就果断a了.状态要设定三个因为和上面两个状态有关,这种状态设定我第一次见,但很好理解,dp[i][j][k] 表示第i行状态为k,第i-1状态为j时的最大炮兵个数。 状态转移方程:dp[i][j][k] =max(dp[i][j][k],dp[i-1][l][j]+cot[k]); cot[k]为k状态中1的个数 ;之后就好做了。

Run IDUserProblemResultMemoryTimeLanguageCode LengthSubmit Time92035022010307204251185Accepted3008K344MSC++1467B2011-08-21 09:05:52

#include<cstdio>#include<string>#include<cstring>#include<iostream>#include<cmath>#include<algorithm>using namespace std;int n,m,sum,num,sta[1<<11],cot[1<<11],dp[105][105][105],a[105];bool fit(int x,int y){if(x&y)return 0;return 1;}void init(){ sum=1<<m;num=0;for(int i=0;i<sum;i++){if(i&(i<<1)||i&(i<<2))continue;sta[num]=i;int tem=i,count=0;while(tem){count++;tem&=tem-1;}cot[num++]=count;}}void DP(){int ans=0;for(int i=0;i<num;i++){if(!fit(a[1],sta[i]))continue;dp[1][0][i]=cot[i];if(ans<dp[1][0][i])ans=dp[1][0][i];}for(int i=2;i<=n;i++)for(int j=0;j<num;j++)for(int k=0;k<num;k++){if(!fit(sta[k],sta[j])||!fit(a[i],sta[k])||!fit(a[i-1],sta[j]))continue;for(int l=0;l<num;l++){if(!fit(sta[k],sta[l])||!fit(sta[j],sta[l])||!fit(a[i-2],sta[l])||!dp[i-1][l][j])continue;dp[i][j][k]=max(dp[i][j][k],dp[i-1][l][j]+cot[k]);if(ans<dp[i][j][k])ans=dp[i][j][k];}}printf("%d\n",ans);}int main(){char s;scanf("%d%d",&n,&m);getchar();init();for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){scanf("%c",&s);if(s=='H'){int tem=1<<(j-1);a[i]+=tem;}}getchar();}DP();return 0;}