f[ i ] [ j ] [ k ] 分别表示, 行数, 当前行的状态表示, 上一行的状态表示。
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 310, M = 110;
int f[M][N][N], n, m;
int num[N], temp[N], map[M], idx;
int get_count(int x)
{
int ans = 0;
while(x > 0)
{
if(x & 1) ans ++;
x >>= 1;
}
return ans;
}
int main()
{
cin >> n >> m;
for(int i = 2; i <= n + 1; i ++)
{
int t = 0;
char a[15]; cin >> a;
for(int j = 0; j < m; j ++) if(a[j] == 'P') t += (1 << j);
map[i] = t;
}
for(int i = 0; i < 1 << m ; i ++)
{
if(i & (i >> 1) || i & (i >> 2)) continue;
temp[idx] = i, num[idx ++] = get_count(i);
}
for(int i = 2; i <= n + 1; i ++)
{
for(int j = 0 ; j < idx ; j ++)
{
if((temp[j] | map[i]) == map[i])
for(int k = 0; k < idx; k ++)
{
if(temp[k] & temp[j]) continue;
for(int r = 0; r < idx ; r ++)
{
if(temp[r] & temp[k] || temp[r] & temp[j]) continue;
f[i][j][k] = max(f[i][j][k], f[i - 1][k][r] + num[j]);
}
}
}
}
int res = 0;
for(int j = 0; j < idx; j ++)
{
for(int k = 0; k < idx; k ++)
{
res = max(res,f[n + 1][j][k]);
}
}
cout << res;
return 0;
}