为什么我第一个点会WA

P2704 [NOI2001] 炮兵阵地

MILLOPE @ 2019-06-10 21:21:55

话说第一个点是样例数据啊 传送门

#include <bits/stdc++.h> 
using namespace std; 
const int maxn = 105; 

template <typename T> 
inline void read(T &s) {
    s = 0; 
    T w = 1, ch = getchar(); 
    while (!isdigit(ch)) { if (ch == '-') w = -1; ch = getchar(); }
    while (isdigit(ch)) { s = (s << 1) + (s << 3) + (ch ^ 48); ch = getchar(); }
    s *= w; 
}

int n, m, cnt, ans; 
int a[maxn], s[maxn], num[maxn]; 
int f[maxn][maxn][maxn];

int main() {
    read(n), read(m); 
    for (int i = 1; i <= n; ++i) {
        for (int j = 0; j < m; ++j) {
            char ch = getchar(); 
//          a[i] = (a[i] << 1) + (ch == 'H' ? 1 : 0); 
            if (ch == 'H') a[i] |= (1 << j); 
            /* 以上两种方法初始化状态应该都行,但是所得二进制数是反过来的233 */ 
        }
        getchar(); 
    }
    for (int i = 0; i < (1 << m); ++i) {
        if ((i & (i << 1)) || (i & (i << 2))) continue; 
        s[++cnt] = i; 
        int t = i; 
        while (t) 
            num[cnt] += t & 1, t >>= 1; 
    }

    for (int i = 1; i <= cnt; ++i) {
        if (s[i] & a[1]) continue; 
        f[1][1][i] = num[i];  
    } 

    for (int i = 2; i <= n; ++i) {
        for (int j = 1; j <= cnt; ++j) { // 当前 
            if (s[j] & a[i]) continue; 
            for (int k = 1; k <= cnt; ++k) { // i-1 
                if (s[j] & s[k]) continue; 
                for (int l = 1; l <= cnt; ++l) { // i-2
                    if (s[j] & s[l]) continue; 
                    if (s[k] & s[l]) continue; 
                    f[i][k][j] = max(f[i][k][j], f[i - 1][l][k] + num[j]); 
                }
            }
        }
    }

    ans = 0; 
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= cnt; ++j) {
            for (int k = 1; k <= cnt; ++k) {
                ans = max(ans, f[i][j][k]); 
            }
        }
    }

    printf("%d\n", ans); 
    return 0; 
}

by ctq1999 @ 2019-06-10 22:39:42

特判吧

有些玄学情况就是这样


|