18.11.8 考试总结

早上的思路是很接近正解了QAQ

$dp[i][sta]$表示到了第$i$层当前的奇偶状态为$sta$的方案数

那么转移下一层就需要考虑当前边的状态 设置$up, dn$为当前的点连接到的前一层的点的状态

那么他的贡献就有当前的状态并上上一层的状态才能够累加贡献 就这样往后推即可

代码

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const ll MOD = 998244353;
const int STA = (1 << 11) + 5;
int m, k;
ll ans = 0, dp[2][STA], pre[STA], up[STA], dn[STA];

void init( ) {
    
    for(int i = 0; i < (1 << k); i ++)
        pre[i] = (i & 1) ^ (pre[i >> 1]);
}

void Moc(ll & a, ll b) {
    a = (a + b) % MOD;
}

int read( ) {
    
    int t = 1, ans = 0;
    char x; x = getchar( );
    while(x < '0' || x > '9') {
        if(x == '-') t = -1;
        x = getchar( );
    }
    while(x >= '0' && x <= '9') {
        ans = ans * 10 + x - '0';
        x = getchar( );
    }
    return ans * t;
}

int main( ) {
    
    freopen("adore.in", "r", stdin);
    freopen("adore.out", "w", stdout);
    m = read( ), k = read( );
    int s = 0;
    for(int i = 0; i < k; i ++) {
        int x; x = read( ); s |= (x << i);
    }
    init( );
    dp[0][s] = 1; int now = 0;
    for(int i = 2; i < m - 1; i ++) {
        now ^= 1;
        memset(dp[now], 0, sizeof(dp[now]));
        memset(up, 0, sizeof(up));
        memset(dn, 0, sizeof(dn));
        for(int u = 0; u < k; u ++)
            for(int v = 0; v < k; v ++) {
                int x; x = read( );
                up[u] |= (x << v); dn[v] |= (x << u);
            }
        for(int sta = 0; sta < (1 << k); sta ++) {
            if(dp[now ^ 1][sta]) {
                int A = 0, B = 0;
                for(int j = 0; j < k; j ++)
                    A |= (pre[sta & up[j]] << j), B |= (pre[sta & dn[j]] << j);
                Moc(dp[now][A], dp[now ^ 1][sta]);
                Moc(dp[now][B], dp[now ^ 1][sta]);
            }
        }
    }
    int sta = 0;
    for(int i = 0; i < k; i ++) {
        int x; x = read( ); sta |= (x << i);
    }
    for(int s = 0; s < (1 << k); s ++) {
        if(! pre[s & sta]) Moc(ans, dp[now][s]);
    }
    printf("%lld\n", ans);
}
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const ll MOD = 998244353;
const int STA = (1 << 11) + 5;
int m, k;
ll ans = 0, dp[2][STA], pre[STA], up[STA], dn[STA];

void init( ) {
    
    for(int i = 0; i < (1 << k); i ++)
        pre[i] = (i & 1) ^ (pre[i >> 1]);
}

void Moc(ll & a, ll b) {
    a = (a + b) % MOD;
}

int read( ) {
    
    int t = 1, ans = 0;
    char x; x = getchar( );
    while(x < '0' || x > '9') {
        if(x == '-') t = -1;
        x = getchar( );
    }
    while(x >= '0' && x <= '9') {
        ans = ans * 10 + x - '0';
        x = getchar( );
    }
    return ans * t;
}

int main( ) {
    
    freopen("adore.in", "r", stdin);
    freopen("adore.out", "w", stdout);
    m = read( ), k = read( );
    int s = 0;
    for(int i = 0; i < k; i ++) {
        int x; x = read( ); s |= (x << i);
    }
    init( );
    dp[0][s] = 1; int now = 0;
    for(int i = 2; i < m - 1; i ++) {
        now ^= 1;
        memset(dp[now], 0, sizeof(dp[now]));
        memset(up, 0, sizeof(up));
        memset(dn, 0, sizeof(dn));
        for(int u = 0; u < k; u ++)
            for(int v = 0; v < k; v ++) {
                int x; x = read( );
                up[u] |= (x << v); dn[v] |= (x << u);
            }
        for(int sta = 0; sta < (1 << k); sta ++) {
            if(dp[now ^ 1][sta]) {
                int A = 0, B = 0;
                for(int j = 0; j < k; j ++)
                    A |= (pre[sta & up[j]] << j), B |= (pre[sta & dn[j]] << j);
                Moc(dp[now][A], dp[now ^ 1][sta]);
                Moc(dp[now][B], dp[now ^ 1][sta]);
            }
        }
    }
    int sta = 0;
    for(int i = 0; i < k; i ++) {
        int x; x = read( ); sta |= (x << i);
    }
    for(int s = 0; s < (1 << k); s ++) {
        if(! pre[s & sta]) Moc(ans, dp[now][s]);
    }
    printf("%lld\n", ans);
}

       

对不起这道题正解随机化:))))

posted @ 2018-11-08 16:24  阿澈说他也想好好学习  阅读(217)  评论(0编辑  收藏  举报