推荐一篇博客,写的超好,很容易理解。
重贴代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXR=110,MAXC=12,MAXS=65;
int state[MAXS],soldier[MAXS],num;
int mp[MAXR]; char MAP[MAXC];
int dp[MAXR][MAXS][MAXS],N,M;
void ReadIn(){
scanf("%d%d",&N,&M);
for(int i=0;i<N;i++) {
scanf("%s",MAP);
for(int j=0;j<M;j++) if(MAP[j] == 'H'){
mp[i] |= (1<<j);
}
}
}
void PreWork() {
num=0;
int i,m=1<<M;
for(i=0;i<m;i++){
if((i&(i>>1)) || (i&(i>>2))) continue;
int cnt=0,t=i;
while(t) cnt+=t&1,t>>=1;
state[num]=i,soldier[num++]=cnt;
}
}
void Init(){
for(int i=0;i<num;i++) {
if(state[i]&mp[0]) continue;
dp[0][i][0] = soldier[i];
}
for(int i=0;i<num;i++){
if(state[i]&mp[1]) continue;
for(int j=0;j<num;j++){
if((state[j]&mp[0]) || (state[i]&state[j])) continue;
dp[1][i][j] = max(dp[1][i][j] , dp[0][j][0] + soldier[i]);
}
}
}
void DP_process(){
for(int r=2;r<N;r++){
for(int i=0;i<num;i++){
if(state[i]&mp[r]) continue;
for(int j=0;j<num;j++){
if((state[j]&mp[r-1]) || (state[i]&state[j])) continue;
for(int k=0;k<num;k++){
if((state[k]&mp[r-2]) || (state[i]&state[k]) || (state[j]&state[k])) continue;
dp[r][i][j] = max(dp[r][i][j] , dp[r-1][j][k] + soldier[i]);
}
}
}
}
}
void Print(){
int ans=0;
for(int i=0;i<num;i++){
for(int j=0;j<num;j++){
ans=max(ans,dp[N-1][i][j]);
}
}
printf("%d\n",ans);
}
int main()
{
ReadIn();
PreWork();
Init();
DP_process();
Print();
}