#include <algorithm>
#include <iostream>
#include <cstdio>
using namespace std;
#define debug(x) cerr << #x << "=" << x << endl;
const int INF = (1<<30);
int gra[110][12],n,m,f[110][100][100],s[110],tot,ans,temte[12],temtot;
void print(int k);
void initialization() {
for(int i=0; i<1<<m; i++) {
int pre=-1;
bool flg = true;
for(int j=0; j<m; j++)
if((i>>j) & 1) {
if(pre>=0 && j-pre<3) { //注意pre>=0,因为最右边第一位可能就是1
flg = false;
break;
}
pre = j;
}
if(flg)
s[++tot] = i;
}
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++)
for(int l=1; l<=m; l++)
f[i][j][l] = -INF;
}
bool dep(int p, int k) {
int tem = s[k];
for(int i=0; i<m; i++)
if(!gra[p][m-i] && (tem >> i & 1))
return false;
return true;
}
void print(int k) {//调试用,输出二进制
k = s[k];
temtot = 0;
for(int i=0; i<m; i++)
temte[++temtot] = (k >> i) & 1;
for(int i=temtot; i>=1; i--)
cout <<temte[i];
cout << endl;
}
int count(int k) {
int tem = s[k];
int sum = 0;
for(int i=0; i<m; i++)
if(tem>>i&1) sum++;
return sum;
}
int main() {
scanf("%d %d", &n, &m);
for(int i=1; i<=n; i++) {
for(int j=1; j<=m; j++) {
char ch;
cin >> ch;
if(ch == 'P') gra[i][j] = 1;
}
}
initialization();
f[0][0][0] = 0;
for(int i=1; i<=n; i++)
for(int j=1; j<=tot; j++)
for(int k=1; k<=tot; k++) {
int temp = -INF;
if(!(s[j] & s[k]) && dep(i,j) && dep(i-1,k) ) {
for(int l=1; l<=tot; l++)
if(!(s[j] & s[l]))
temp = max(temp, f[i-1][k][l]);
f[i][j][k] = temp + count(j);
}
}
for(int i=1; i<=tot; i++)
for(int j=1; j<=tot; j++)
if(!(s[i] & s[j]) && dep(n,i) && dep(n-1,j))
ans = max(ans, f[n][i][j]);
printf("%d\n", ans);
return 0;
}
NOI2001 炮兵阵地 - 状压DP
猜你喜欢
转载自blog.csdn.net/fantasy_world/article/details/80289525
今日推荐
周排行