zoukankan      html  css  js  c++  java
  • [CF1271D] Portals

    起初你有 (k) 个兵,你需要按顺序攻占 (n) 座城堡。为了占领第 (i) 座城堡,你需要至少 (a_i) 个士兵,士兵不会死,攻占成功后你可以获得 (b_i) 个士兵。攻占完一座城堡你可以派出至少一个兵驻守来获得这座城堡的分数 (c_i),你可以在你攻占完城堡 (i) 后立即派兵下车,或者在有向图上通向这个点的点处派兵下车。你需要在保证能攻占所有城堡的前提下,最大化你的得分。(n leq 5000, mleq 3 imes 10^5),队伍中的人数无论如何不会超过 (5000)

    Solution

    对于城堡 (i),如果要对它派兵,那么一定会在最后一个能向他派兵的地方派兵

    于是我们只需要考察其中的 (n) 条边即可

    (f[i][j]) 表示在第 (i) 个城堡处,还剩 (j) 个士兵的最大收益

    类似 (01) 背包的暴力转移

    #include <bits/stdc++.h>
    using namespace std;
    
    #define int long long
    const int N = 5005;
    const int K = 5001;
    int n,m,k,r[N],a[N],b[N],c[N],f[N][N];
    vector <int> g[N];
    
    signed main() {
        ios::sync_with_stdio(false);
        cin>>n>>m>>k;
        for(int i=1;i<=n;i++) cin>>a[i]>>b[i]>>c[i];
        for(int i=1;i<=n;i++) r[i]=i;
        for(int i=1;i<=m;i++) {
            int u,v;
            cin>>u>>v;
            r[v]=max(r[v],u);
        }
        for(int i=1;i<=n;i++) {
            g[r[i]].push_back(i);
        }
        memset(f,-0x3f,sizeof f);
        f[0][k]=0;
        for(int i=1;i<=n;i++) {
            for(int j=a[i]+b[i];j<=K;j++) f[i][j]=f[i-1][j-b[i]];
            for(int q:g[i]) {
                for(int j=0;j<=K;j++) //!
                    f[i][j]=max(f[i][j],f[i][j+1]+c[q]);
            }
        }
        int ans = *max_element(f[n],f[n]+K);
        if(ans<0) cout<<-1;
        else cout<<ans;
    }
    
    
  • 相关阅读:
    Learning to Compare: Relation Network for Few-Shot Learning 论文笔记
    修改python import模块中的变量
    roslaunch保存的log文件没有打印的ERROR信息
    python json demo
    vscode 1.32.x按下鼠标左键无法拖曳选择,而旧一点的版本1.30.2可以
    java-ee--------jdbc
    集合
    关键字
    java面向对象
    数组
  • 原文地址:https://www.cnblogs.com/mollnn/p/12505125.html
Copyright © 2011-2022 走看看