• Codeforces Round #207 (Div. 1) D


    D - Bags and Coins

    思路:我们可以这样构造,最大的那个肯定是作为以一个树根,所以我们只要找到一个序列a1 + a2 + a3 .... + ak 并且ak为

    所有点中最大的那个,那么我们a1, a2, a3..., ak-1 作为单独的点,其他没有涉及到的点套在ak的里面。 

    现在问题变成了找出a1, a2, a3, a4, ... , ak。 可以用bitset优化普通dp,因为要找路径,空间开不下,所以需要分段。

    #include<bits/stdc++.h>
    #define LL long long
    #define fi first
    #define se second
    #define mk make_pair
    #define PLL pair<LL, LL>
    #define PLI pair<LL, int>
    #define PII pair<int, int>
    #define SZ(x) ((int)x.size())
    #define ull unsigned long long
    using namespace std;
    
    const int N = 70000 + 7;
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    const int mod = 1e9 + 7;
    const double eps = 1e-8;
    
    int n, s;
    PII a[N];
    bitset<70001> dp[N/10];
    bitset<70001> dp2;
    bitset<70001> tmp;
    vector<int> edge[N];
    vector<PII> dol;
    int c[N];
    bool in[N];
    
    bool ok(int x, int y) {
        if(y < 0) return false;
        dp2 = dp[x/10];
        for(int i = x/10*10+1; i <= x; i++)
            dp2 |= (dp2 << a[i].fi);
        return dp2[y];
    }
    
    int main() {
        scanf("%d%d", &n, &s);
        for(int i = 1; i <= n; i++) {
            scanf("%d", &a[i].fi);
            a[i].se = i;
        }
        sort(a+1, a+1+n);
        int tar = s - a[n].fi;
        tmp[0] = 1; dp[0] = tmp;
        for(int i = 1; i < n; i++) {
            tmp |= (tmp<<a[i].fi);
            if(i % 10 == 0) dp[i/10] = tmp;
        }
        if(ok(n-1, tar)) {
            for(int i = n-1, now = tar; i >= 1; i--) {
                if(now >= a[i].fi && ok(i-1, now-a[i].fi)) {
                    now = now - a[i].fi;
                    in[a[i].se] = true;
                }
            }
            for(int i = 1; i < n; i++) {
                if(in[a[i].se]) {
                    c[a[i].se] = a[i].fi;
                } else {
                    dol.push_back(a[i]);
                }
            }
            dol.push_back(a[n]);
            for(int i = 0; i < dol.size(); i++) {
                if(i) {
                    c[dol[i].se] = dol[i].fi - dol[i-1].fi;
                    edge[dol[i].se].push_back(dol[i-1].se);
                } else {
                    c[dol[i].se] = dol[i].fi;
                }
            }
            for(int i = 1; i <= n; i++) {
                printf("%d %d ", c[i], edge[i].size());
                for(int j : edge[i]) printf("%d ", j);
                puts("");
            }
        } else {
            puts("-1");
        }
        return 0;
    }
    
    /*
    */
  • 相关阅读:
    设备树(Device Tree)
    深度Linux Deepin系统安装教程使用体验
    Qt Creator的安装与Qt交叉编译的配置
    移植tslib和Qt5.6到三星s5pv210开发板
    Linux下读取RFID卡号(C串口编程)
    如何移植openwrt系统
    如何在Qt Creator中添加库文件和头文件目录
    Qt Creator中如何选择某个子项目为启动项目
    QT中子目录调用另一个子目录
    在Qt项目中如何添加一个已有的项目作为子项目
  • 原文地址:https://www.cnblogs.com/CJLHY/p/10098141.html
Copyright © 2020-2023  润新知