社区讨论

这题怎么卡常啊/ll

CF2097FLost Luggage参与者 3已保存回复 3

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
3 条
当前快照
1 份
快照标识符
@mkcedocs
此快照首次捕获于
2026/01/13 17:36
上个月
此快照最后确认于
2026/01/17 10:45
上个月
查看原帖
根据第一篇题解写的 dp,状态数已经 4nm2n4 * nm * 2^n 了,转移的时候还要枚举 88 次来判断三条边是否割掉,这咋卡常啊/yun
CPP
#include<bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
using namespace std;
auto IOS = ios::sync_with_stdio(false);
auto CIN = cin.tie(nullptr);
int mread(){
    int x = 0, f = 1;
    char c = cin.get();
    while(c < '0' || c > '9'){
        if(c == '-'){
            f = -1;
        }
        c = cin.get();
    }
    while(c >= '0' && c <= '9'){
        x = x * 10 + c - '0';
        c = cin.get();
    }
    return x * f;
}
const int N = 3005;
const int inf = 1200000000;
int t = mread(), a[N][20], b[N][20], c[N][20], s[20];
int tmp[N][20][8], nxt[2048][20][8];
// 第一维表示天数,滚动,第二维表示状态,第三维表示当前应该考虑哪个点,为 0 则代表考虑完了,第四维表示 n - 1 是否被迫联通,第五维代表即将考虑的点是否被迫联通
int f[2][2048][13][2][2];
void get(int &x, int y){
    if(y < x){
        x = y;
    }
    return;
}
signed main(){
    while(t --){
        int n = mread(), m = mread();
        for(int i = 0; i < n; i ++){
            s[i] = mread();
        }
        for(int i = 1; i <= m; i ++){
            for(int j = 0; j < n; j ++){
                a[i][j] = mread();
            }
            for(int j = 0; j < n; j ++){
                b[i][j] = mread();
            }
            for(int j = 0; j < n; j ++){
                c[i][j] = mread();
            }
        }
        int ma = 1 << n;
        for(int i = 0; i < 2; i ++){
            for(int j = 0; j < ma; j ++){
                for(int k = 0; k <= n; k ++){
                    for(int l = 0; l < 4; l ++){
                        f[i][j][k][l & 1][l >> 1 & 1] = inf;
                    }
                }
            }
        }
        for(int now = 0; now < ma; now ++){
            f[0][now][0][0][0] = 0;
            for(int i = 0; i < n; i ++){
                if(!(now >> i & 1)){
                    f[0][now][0][0][0] += s[i];
                }
            }
        }
        for(int t = 1; t <= m; t ++){
            for(int i = 0; i < n; i ++){
                for(int vt = 0; vt < 8; vt ++){
                    tmp[t][i][vt] = 0;
                    if(vt >> 0 & 1){
                        tmp[t][i][vt] += a[t][i];
                    }
                    if(vt >> 1 & 1){
                        tmp[t][i][vt] += b[t][i];
                    }
                    if(vt >> 2 & 1){
                        tmp[t][i][vt] += c[t][i];
                    }
                }
            }
        }
        for(int now = 0; now < ma; now ++){
            for(int i = 1; i < n; i ++){
                for(int vt = 0; vt < 8; vt ++){
                    nxt[now][i][vt] = now;
                    if(vt >> 0 & 1){
                    }
                    else{
                        nxt[now][i][vt] |= 1 << i - 1;
                    }
                    if(vt >> 1 & 1){
                        nxt[now][i][vt] -= 1 << i;
                    }
                }
            }
        }
        for(int now = 0; now < ma; now ++){
            if(now >> 0 & 1){
                for(int t = 0; t < 8; t ++){
                    int nxt = now;
                    int t0 = 1, t2 = 1;
                    int tmp = f[0][now][0][0][0];
                    if(t >> 0 & 1){
                        t0 = 0, tmp += a[1][0];
                    }
                    if(t >> 1 & 1){
                        nxt -= 1, tmp += b[1][0];
                    }
                    if(t >> 2 & 1){
                        t2 = 0, tmp += c[1][0];
                    }
                    get(f[1][nxt][1][t0][t2], tmp);
                }
            }
            else{
                get(f[1][now][1][0][0], f[0][now][0][0][0]);
            }
            f[0][now][0][0][0] = inf;
        }
        for(int t = 1; t <= m; t ++){
            for(int i = 1; i < n; i ++){
                for(int now = 0; now < ma; now ++){
                    for(int t0 = 0; t0 <= 1; t0 ++){
                        for(int t2 = 0; t2 <= 1; t2 ++){
                            if(f[t & 1][now][i][t0][t2] == inf){
                                continue;
                            }
                            // printf("*** %d %d %d %d %d %intd\n", t, now, i, t0, t2, f[t & 1][now][i][t0][t2]);
                            if(now >> i & 1){
                                for(int vt = 0; vt < 8; vt ++){
                                    get(f[t & 1][nxt[now][i][vt] | (t2 << i)][i + 1][t0][!(vt >> 2 & 1)], f[t & 1][now][i][t0][t2] + tmp[t][i][vt]);
                                }
                            }
                            else{
                                get(f[t & 1][now | (t2 << i)][i + 1][t0][0], f[t & 1][now][i][t0][t2]);
                            }
                            f[t & 1][now][i][t0][t2] = inf;
                        }
                    }
                }
            }
            for(int now = 0; now < ma; now ++){
                for(int t0 = 0; t0 <= 1; t0 ++){
                    for(int t2 = 0; t2 <= 1; t2 ++){
                        get(f[t & 1][now | (t0 << n - 1) | t2][0][0][0], f[t & 1][now][n][t0][t2]);
                        f[t & 1][now][n][t0][t2] = inf;
                    }
                }
            }
            cout << f[t & 1][0][0][0][0] << "\n";
            if(t == m){
                break;
            }
            for(int now = 0; now < ma; now ++){
                if(now >> 0 & 1){
                    for(int vt = 0; vt < 8; vt ++){
                        int nxt = now;
                        int vt2 = 1, vt0 = 1;
                        int tmp = f[t & 1][now][0][0][0];
                        if(vt >> 0 & 1){
                            vt0 = 0, tmp += a[t + 1][0];
                        }
                        if(vt >> 1 & 1){
                            nxt -= 1, tmp += b[t + 1][0];
                        }
                        if(vt >> 2 & 1){
                            vt2 = 0, tmp += c[t + 1][0];
                        }
                        get(f[t + 1 & 1][nxt][1][vt0][vt2], tmp);
                    }
                }
                else{
                    get(f[t + 1 & 1][now][1][0][0], f[t & 1][now][0][0][0]);
                }
                f[t & 1][now][0][0][0] = inf;
            }
        }
    }
    return 0;
}

回复

3 条回复,欢迎继续交流。

正在加载回复...