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;
}

贪心

原文地址:https://www.cnblogs.com/bxd123/p/12076644.html

时间: 2024-08-30 02:07:34

CF1271D Portals dp 贪心的相关文章

codeforces219C - Color Stripe DP+贪心

题意:给你n,k,大意就是说给你一个已经涂满颜色长为n的字符串,现有k种颜色可以选择,问你最少要改变多少个箱子的颜色使得相邻箱子之间颜色不同. 解题思路:当k = 2 时单独讨论,不能用贪心,其余情况都可贪心得到. 解题代码: 1 // File Name: 219c.cpp 2 // Author: darkdream 3 // Created Time: 2014年07月26日 星期六 15时45分56秒 4 5 #include<vector> 6 #include<list>

ZOJ 2109 FatMouse&#39; Trade (背包 dp + 贪心)

链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1109 FatMouse prepared M pounds of cat food, ready to trade with the cats guarding the warehouse containing his favorite food, JavaBean. The warehouse has N rooms. The i-th room contains J

UVALive 4731 dp+贪心

这个题首先要利用题目的特性,先贪心,否则无法进行DP 因为求期望的话,越后面的乘的越大,所以为了得到最小值,应该把概率值降序排序,把大的数跟小的系数相乘 然后这种dp的特性就是转移的时候,由 i推到i+1每次添加一个数,就要考虑这个新数应该和谁放在一组,枚举他放在哪一组即可 dp[i][j]代表当前第i个数有j个分组时候的最小值 dp[i][j]=dp[k][j-1]+i(prefix[i]-prefix[k-1]),k代表枚举第几个数开始和当前新添加的数为一组,prefix为前缀和,为了迅速得

HDU 5303(Delicious Apples- 环上折半dp+贪心)

Delicious Apples Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others) Total Submission(s): 1585    Accepted Submission(s): 514 Problem Description There are n apple trees planted along a cyclic road, which is L metres

Codeforces 459E Pashmak and Graph(dp+贪心)

题目链接:Codeforces 459E Pashmak and Graph 题目大意:给定一张有向图,每条边有它的权值,要求选定一条路线,保证所经过的边权值严格递增,输出最长路径. 解题思路:将边按照权值排序,每次将相同权值的边同时加入,维护每个点作为终止点的最大长度即可. #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 3

Codeforces 77C 树形dp + 贪心

题目链接:点击打开链接 题意: 给定n个点, 每个点的豆子数量 下面是一棵树 再给出起点 每走到一个点,就会把那个点的豆子吃掉一颗. 问:回到起点最多能吃掉多少颗豆子 思路:树形dp 对于当前节点u,先把子节点v都走一次. 然后再往返于(u,v) 之间,直到u点没有豆子或者v点没有豆子. dp[u] 表示u点的最大值.a[u] 是u点剩下的豆子数. #include <cstdio> #include <vector> #include <algorithm> #inc

uva 1534 - Taekwondo(dp+贪心)

题目连接:uva 1534 - Taekwondo 题目大意:有两组什么东西,题目背景有点忘记了,就是给出两组数,两组个数分别为n,m,要求找出min(n,m)对数,每个数最多最多选一次,使得这min(n,m)对数ai,bi,ai-bi的绝对值之和最小. 解题思路:贪心,将两组数分别排序,然后dp[i][j]表示i对,匹配到j时候的最优解. #include <cstdio> #include <cstring> #include <cmath> #include &l

Codeforces 830A. Office Keys (背包dp+贪心) / (二分+贪心)

题目链接: http://codeforces.com/problemset/problem/830/A 题意: n个人,k个钥匙(n<=k),p表示这些人要到达的位置 给出n个人的位置以及钥匙的位置,问花时间最多的那个人用时最少是多少?? 思路: 二分+贪心: 二分最少时间,需要对a,b位置数组排序,我们check函数只需要从左到右一个一个找过去,因为如果选后边的点,可能会使结果更差,假如当前这个人选后面的点,那可能会选中后面的人可以选的唯一的钥匙,不会使解更优. check(40)的时候答案

HDU 4939 Stupid Tower Defense(dp+贪心)

dp[i][j]表示到了第i步放了j个减速,造成的伤害.我们用贪心的策略把造成一段伤害的放在最后面,造成持续伤害的与减速放在前i个中这样得到的伤害是最高的. 所以前(i,j)中的伤害为dp[i][j] = max(dp[i-1][j]+(j*z+t)*(max(0LL, i-1-j))*y, dp[i-1][j-1]+((j-1)*z+t)*(i-j)*y); 每次造成的伤害就为:dp[i][j]+(n-i)*(j*z+t)*(x+(i-j)*y).然后取一个最大值,就是伤害的最大值了. Stu