一行的状态不仅仅与上一行有关系,而且与上一行的上一行的有关系。
那就同时记录最近2行的状态进行DP吧。。。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
const int maxn = 1 << 10;
int dp[110][200][200];
int map[110], m, n;
vector<int> numbers[110];
int bit_num[maxn + 10];
int count_bit(int num)
{
return num == 0 ? 0 : (num & 1) + count_bit(num / 2);
}
bool check(int num)
{
if(num & (num << 1)) return false;
if(num & (num << 2)) return false;
return true;
}
int main()
{
for(int i = 0; i <= maxn; ++i)
{
bit_num[i] = count_bit(i);
// cout << i << " " << bit_num[i] << "\n";
}
freopen("in", "r", stdin);
while(~scanf("%d %d", &n, &m))
{
memset(dp, 0, sizeof(dp));
for(int i = 1; i <= n; ++i)
{
char str[100];
scanf("%s", str);
map[i] = 0;
for(int j = 0; str[j]; ++j)
{
if(str[j] == 'H') map[i] |= (1 << j);
}
numbers[i].clear();
for(int j = 0; j < (1 << m); ++j)
{
if(j & map[i] || !check(j)) continue;
numbers[i].push_back(j);
}
}
int res = 0;
if(n == 0) { printf("0\n"); continue; }
if(n == 1)
{
for(int i = 0; i < numbers[1].size(); ++i)
res = max(res, bit_num[numbers[1][i]]);
printf("%d\n", res);
continue;
}
for(int i = 0; i < numbers[1].size(); ++i)
{
for(int j = 0; j < numbers[2].size(); ++j)
{
int a = numbers[1][i], b = numbers[2][j];
if(a & b) continue;
dp[2][j][i] = bit_num[a] + bit_num[b];
res = max(res, dp[2][j][i]);
}
}
for(int i = 3; i <= n; ++i)
{
for(int j = 0; j < numbers[i].size(); ++j)
{
for(int k = 0; k < numbers[i - 1].size(); ++k)
{
int a = numbers[i][j], b = numbers[i - 1][k];
if(a & b) continue;
for(int q = 0; q < numbers[i - 2].size(); ++q)
{
int c = numbers[i - 2][q];
if(c & a || c & b) continue;
dp[i][j][k] = max(dp[i][j][k], dp[i - 1][k][q] + bit_num[a]);
res = max(res, dp[i][j][k]);
}
}
}
}
printf("%d\n", res);
}
return 0;
}