P1504 积木城堡

58 阅读1分钟

P1504 积木城堡

题目给出 nn 个数组,每个数组里面可以删除一些数。最终使得每个数组的剩余元素的和相同被称为一个合法方案,求合法方案中数组元素的最大和。

buildibuild_i 表示有多少个数组能构造为和等于 iifi=0/1f_i=0/1 表示来到每个数组时,和 ii 能否被构建出来。

对于每个数组求 ff 数组的过程,相当于 0/10/1 背包。最终对 fi=1f_i=1 的所有 ii 使其 buildi+1build_i+1

最后对于所有 buildi=nbuild_i=n ,即能被构造出来的方案,取 ii 的最大值。

时间复杂度:O(n×100×m)O(n\times 100 \times m) ,其中 100 表示一个数组积木最多多少块,m=100×100m=100\times 100 表示最大高度。

void solve(){
    int n;
    cin >> n;
    vector<int> f(1E4 + 1, 0);
    vector<int> build(1E4 + 1, 0);
    for(int i = 1; i <= n; i ++) {
        int x;
        vector<int> v;
        while(cin >> x, x != -1) {
            v.push_back(x);
        }
        fill(f.begin(), f.end(), 0);
        f[0] = 1;
        for(auto &nx : v) {
            for(int j = 1E4; j >= 0; j --) {
                if(f[j] && j + nx <= 1E4) {
                    f[j + nx] = 1;
                }
            }
        }
        for(int j = 0; j <= 1E4; j ++) {
            if(f[j]) {
                build[j] ++;
            }
        }
    }

    for(int i = 1E4; i >= 0; i --) {
        if(build[i] == n) {
            cout << i << '\n';
            return ;
        }
    }
}