zoukankan      html  css  js  c++  java
  • CF1271D Portals dp 贪心

    地址

    • 首先可以观察得出:  如果可以defence 城堡i有多个城市,那么选择最后一个城市再考虑是否defence该城堡是最优方案
    • 第一种方法 可以采用dp 因为发现士兵数量C 小于5000  所以设置dp[i]表示攻打到当前城堡时,士兵数剩余i个所取得的最大贡献
    • 第二种方法 可以用优先队列优化
    • 要求出第i个城市最多可以使用多少个额外的士兵非常的麻烦
    • 可以用反悔贪心法
    • 如果能占领城市那么就去占领, 如果攻打下一个城市缺人, 那么可以将之前派去的士兵召集回来
    • 用一个小顶堆存放派去的士兵,这样如果召回的话损失也最小
     #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
     
    const int inf=0x3f3f3f3f;
    const int N=5e5+100;
     
    int dp[6000],a[N],b[N],c[N];
    vector<int>contribution[N];
    int last[N];
    int main () {
        int n,m,k;
        cin>>n>>m>>k;
        for(int i=1;i<=n;i++) {
            scanf("%d%d%d",&a[i],&b[i],&c[i]);
            last[i]=i;
        }
        int u,v;
        while(m--) {
            scanf("%d%d",&u,&v);
            last[v]=max(last[v],u);
        }
        for(int i=1;i<=n;i++) contribution[last[i]].push_back(c[i]);
        memset(dp,-1,sizeof dp);
        dp[k]=0;
     
        for(int i=1;i<=n;i++) {
            for(int j=0;j<a[i];j++) dp[j]=-1;
     
            for(int j=5500;j>=b[i];j--) dp[j]=dp[j-b[i]];
     
            for(auto &v:contribution[i])
                for(int j=0;j<=5500;j++)
                    if(dp[j+1]!=-1)
                        dp[j]=max(dp[j],dp[j+1]+v);
        }
        cout<<*max_element(dp,dp+5500);
    }
    dp
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    const int N=3e5+10;
    
    int a[N],b[N],c[N],last[N];
    vector<int>contribution[N];
    
    int main() {
        int n,m,k;
        cin>>n>>m>>k;
        for(int i=1;i<=n;i++) scanf("%d%d%d",&a[i],&b[i],&c[i]),last[i]=i;
        int u,v;
        while(m--) scanf("%d%d",&u,&v),last[v]=max(last[v],u);
        for(int i=1;i<=n;i++)
            contribution[last[i]].push_back(c[i]);
        priority_queue<int ,vector<int>, greater<int> >q;
        int sum=k,ans=0;
        for(int i=0;i<=n;i++) {
            sum+=b[i];
            for(auto &v:contribution[i])
                sum--,q.push(v);
    
            while(!q.empty()&&sum<a[i+1])
                sum++,q.pop();
    
            if(sum<a[i+1]) printf("-1"),exit(0);
        }
        while(!q.empty())
            ans+=q.top(),q.pop();
        cout<<ans;
    }
    贪心
  • 相关阅读:
    自动封箱和拆箱
    关于Java的一道内存的题目
    volatile关键字
    阶乘尾零
    Java之final的解析
    从1到n整数中1出现的次数
    最小安装雷达数量
    二叉树重建
    最短路径—Dijkstra算法
    PAT A1063——set的常见用法详解
  • 原文地址:https://www.cnblogs.com/bxd123/p/12076644.html
Copyright © 2011-2022 走看看