来源:POJ1185
对于影响因素的个数来判断需要的维度,根据状态的多少来开辟数组
对于各个状态进行一个比较,注意使用压缩的方法对于问题中的所有东西进行优化
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int n,m;
const int N=100+5;
const int M=10;
const int MAXN= (1<<10)+5;
int dp[N][N][N];
//dp[floor][prestate][currstate]
int mp[N];
char ch;
int st[100];
int sum[100];
/*
dp关键是要找出那些量杜宇当前状态的决策会产生影响,而这个影响的种类往往确定维度
dp[r][i][j]=max{dp[r-1][j][k]}+sum[i]
*/
bool judge(int x){
if(x&(x<<1)) return false;
if(x&(x<<2)) return false;
return true;
}
int asksum(int x){
int cnt=0;
while(x>0){
if(x&1) cnt++;
x>>=1;
}
return cnt;
}
int main(){
while(scanf("%d%d",&n,&m)!=EOF){
getchar();
memset(mp,0,sizeof(mp));
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
scanf("%c",&ch);
if(ch=='H'){
mp[i]|=(1<<j);
//cout<<i<<" "<<j<<endl;
}
//cout<<ch;
}
getchar();
//cout<<endl;
}
memset(dp,-1,sizeof(dp));
int k=0;
for(int j=0;j<(1<<m);j++){
if(judge(j)){
st[k]=j;
sum[k++]=asksum(j);
//cout<<sum[k-1]<<endl;
}
}
//cout<<"k: "<<k<<endl;
for(int i=0;i<k;i++)
if(!(mp[0]&st[i])) {//youdu
dp[0][0][i]=sum[i];
//cout<<sum[i]<<endl;
}
for(int floor=1; floor<n; floor++){
for(int stn1=0; stn1<k; stn1++){
if(st[stn1] & mp[floor]) continue;
//cout<<"dd"<<endl;
for(int stn2=0; stn2<k; stn2++){
if(st[stn1] & st[stn2]) continue;
//cout<<"kk"<<endl;
for(int stn3=0; stn3<k; stn3++){
if(st[stn1] & st[stn3]) continue;
//cout<<"cc"<<endl;
if(dp[floor-1][stn3][stn2]==-1) continue;
dp[floor][stn2][stn1]=max(dp[floor][stn2][stn1],dp[floor-1][stn3][stn2]+sum[stn1]);
/*if(floor==n-1) {
cout<<dp[n-1][stn2][stn1]<<endl;
}*/
}
}
}
}
//cout<<"-----------"<<endl;
int ans=0;
for(int i=0;i<k;i++){
for(int j=0;j<k;j++){
ans=max(ans,dp[n-1][i][j]);
//cout<<dp[n-1][i][j]<<endl;
}
}
cout/*<<"ans: "*/<<ans<<endl;
}
return 0;
}