蒟蒻求救,样例过了只得10分

P2704 [NOI2001] 炮兵阵地

丶雖 @ 2019-08-09 19:56:30

include<bits/stdc++.h>

define ll long long

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


|