丶雖 @ 2019-08-09 19:56:30
using namespace std;
char s;
ll f[3][100][100];
ll c[105], can[1 << 10], num[1 << 10], ans = -1, n, m, tot;
int count(ll x) {
int ans = 0;
while(x)
{
x -= (x & -x);
ans++;
}
return ans;
}
int main() {
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
{
scanf("%c", &s);
if(s == 'P')
c[i] = (c[i] << 1) + 1;
else
c[i] = c[i] << 1;
}
for(int i = 0; i <= (1 << m) - 1; i++)
if(!((i << 1) & i) && !((i << 2) & i) && !((i >> 1) & i) && !((i >> 2) & i))
{
can[++tot] = i;
num[tot] = count(i);
}
for(int i = 1; i <= tot; i++)
if((can[i] | c[1]) == c[1])
f[1][i][0] = num[i];
for(int i = 1; i <= tot; i++)
for(int j = 1; j <= tot; j++)
if((can[i] | c[2]) == c[2] && (can[j] | c[1]) == c[1] && (can[i] & can[j]) == 0)
f[2][i][j] = num[i] + num[j];
for(int i = 3; i <= n; i++)
for(int j = 1; j <= tot; j++)
{
if((can[j] | c[i]) != c[i])
continue;
for(int k = 1; k <= tot; k++)
{
if((can[k] | c[i - 1]) != c[i - 1] || (can[j] & can[k]))
continue;
for(int p = 1; p <= tot; p++)
{
if((can[p] | c[i - 2]) == c[i - 2] && !(can[p] & can[k]) && !(can[p] & can[j]))
f[i % 3][j][k] = max(f[(i - 1) % 3][k][p] + num[j], f[i % 3][j][k]);
}
}
}
for(int i = 1; i <= tot; i++)
for(int j = 1; j <= tot; j++)
ans = max(f[n % 3][i][j], ans);
printf("%d\n", ans);
return 0;
}
by 木木! @ 2019-08-31 18:02:11
希望更丰富的展现?使用Markdown