Title Description
answer
This question is really cancer ...
First observation range to the column is small, this revelation we use state compression algorithm.
We can not pre-processing the digital all horizontal attack each other, it is clear that only a few hundred of these two. Memory array with b.
We observed that if a line can prevent the artillery and the two lines is determined, we set denotes status line is The first line status It can be placed up to artillery.
So we set up so that a state is l, there is a state transition equation is obvious:
In this case, we need to consider the state of the transfer restriction conditions equation:
- Clearly, in order to prevent another attack, we must first meet and .
- To make both in the plains, to be met .
- Then we let (if ), the rest is negative infinity. and also, represents the number of i is the binary number 1.
code show as below:
#include <bits/stdc++.h>
using namespace std;
const int N = 200;
int n, m, ans = 0, s = 0;
int a[N], f[N][N][N], b[N], c[N];
bool check(int x)
{
int t[20] = {};
for (int i=m-1;i>=0;--i)
t[i+1] = x >> i & 1;
for (int i=3;i<=m;++i)
if (t[i]+t[i-1]+t[i-2] > 1) return 0;
return 1;
}
bool valid(int x,int y) {
return (x | a[y]) == a[y];
}
bool safe(int x,int y,int z) {
return (b[x] & b[y]) == 0 && (b[y] & b[z]) == 0 && (b[x] &b[z]) == 0;
}
int count(int x) {
int cnt = 0;
while (x > 0) cnt += x&1, x >>= 1;
return cnt;
}
int main(void)
{
freopen("input.in","r",stdin);
freopen("output.out","w",stdout);
cin >> n >> m;
for (int i=1;i<=n;++i)
{
int s = 0;
for (int j=1;j<=m;++j)
{
char c;
cin >> c;
if (c == 'P') s = s<<1|1;
else s = s<<1;
}
a[i] = s;
}
for (int i=0;i<1<<m;++i)
if (check(i)) b[++s] = i, c[s] = count(i);
memset(f,-30,sizeof f);
f[0][1][1] = 0;
for (int i=1;i<=n;++i)
for (int j=1;j<=s;++j) if (valid(b[j],i))
for (int k=1;k<=s;++k) if (valid(b[k],i-1) && (b[j]&b[k]) == 0)
for (int l=1;l<=s;++l) if ((b[j]&b[l]) == 0)
f[i][j][k] = max(f[i][j][k],f[i-1][k][l]+c[j]), ans = max(ans,f[i][j][k]);
cout << ans << endl;
return 0;
}