51Nod 最高奖励问题

Question

有N个任务,每个任务有一个最晚结束时间以及一个对应的奖励。

在结束时间之前完成该任务,就可以获得对应的奖励。

完成每一个任务所需的时间都是1个单位时间。

有时候完成所有任务是不可能的,因为时间上可能会有冲突,这需要你来取舍。求能够获得的最高奖励。

Input

第1行:一个数N,表示任务的数量(2 <= N <= 50000)
第2 - N + 1行,每行2个数,中间用空格分隔,表示任务的最晚结束时间E[i]以及对应的奖励W[i]。(1 <= E[i] <= 10^9,1 <= W[i] <= 10^9)

Output

输出能够获得的最高奖励。

Input示例

7
4 20
2 60
4 70
3 40
1 30
4 50
6 10

Output示例

230



我想到的第一个思路是:很麻烦的。。emm,,赶时间的话,可忽略。(按照他能获得的奖励从大到小排序)(如果相等,就让结束时间靠后的在前面)(然后用一个数组记录1到1,1到2,1到3,……1到结束时间最大的那个的空间,也就是在这个空间内,和这个数相等或者小于他的有多少)(用一个bool数组记录在某个时间结束这个时间点是否出现过)(然后循环枚举,没有出现就设为出现,ans+=奖励)(操作时同时,这个时间点到最大的时间点之间所有的记录数组都要减一,)(因为在此空间里又多加了一个数,所以少一个空间)(然后若是遇到了结束时间相等的,)(那就判断一下他前面那个结束时间的位置有没有被占)(他前面那个结束时间不是排完序的那个,,是按照1,2,3,4,5……来的那个)(如果也被占了的话,就继续往前推)(在此过程中如果这个结束时间对应的记录空间的数组等于0的话,(那其实一开始就是0了),)(那就break掉,不用再继续了)。嗯,,基本就是这样,,开了很多数组,思路也很麻烦,可能写错了。。刚开始mle,,最后wa了一个点,t了三四个点。。

代码是这样的。:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#define MAXN 9999
using namespace std;

int n,maxn=-1;
int b[MAXN],x,s;
long long ans;
bool c[MAXN],q;

struct node{
    int end;
    int value;
}a[50002];

bool cmp(node x,node y)
{
    if(x.value !=y.value )
        return x.value >y.value ;
    else return x.end >y.end ;
}

int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;++i)
    {
        scanf("%d%d",&a[i].end ,&a[i].value );
        maxn=max(maxn,a[i].end );
    }
    for(int i=1;i<=maxn;++i)
        b[i]=i;
    sort(a+1,a+n+1,cmp);
    for(int i=1;i<=n;++i)
    {
        x=a[i].end ;
        s=a[i].value ;
        if(b[x])
        {
            if(!c[x])
            {
                ans+=s;
                c[x]=1;
                for(int j=x;j<=maxn;++j)
                    b[j]--;
                continue;
            }
            while(c[x])
            {
                x--;
                if(x==0)
                    break;
                if(!c[x]&&b[x])
                {
                    c[x]=1;
                    ans+=s;
                    for(int j=x;j<=maxn;++j)
                        b[j]--;
                    break;
                }
            }
        }
    }
    printf("%lld",ans);
    return 0;
}

75.。



还是要考虑别的简单的思路。。
小根堆啊!!!按照结束时间从小到大排序!按次序加,如果有更优的,就把最小的踢出去!!

具体看代码吧!手模一遍样例就懂了!好强的贪心思路。。。代码:

 1 #include<queue>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<iostream>
 5 #include<algorithm>
 6 using namespace std;
 7
 8 priority_queue<int ,vector<int >,greater<int> >q;
 9 long long n,ans,s;
10
11 struct node
12 {
13     int end,value;
14 } a[50002];
15
16 bool cmp(node a,node b)
17 {
18     return a.end<b.end;
19 }
20
21 int main()
22 {
23     scanf("%d",&n);
24     for(int i=1; i<=n; i++)
25         scanf("%d%d",&a[i].end,&a[i].value);
26     sort(a+1,a+1+n,cmp);
27     for(int i=1; i<=n; i++)
28     {
29         s=a[i].value;
30         if(a[i].end>q.size())
31         {
32             ans+=s;
33             q.push(s);
34         }
35         else
36         {
37             ans+=s;
38             q.push(s);
39             ans-=q.top();
40             q.pop();
41         }
42     }
43     printf("%lld",ans);
44     return 0;
45 }



如果你不开心,那我就把右边这个帅傻子分享给你吧,

你看,他这么好看,那么深情的望着你,你还伤心吗?

真的!这照片盯上他五秒钟就想笑了。

一切都会过去的。

 

原文地址:https://www.cnblogs.com/Mary-Sue/p/9454954.html

时间: 2024-07-31 14:28:13

51Nod 最高奖励问题的相关文章

51nod 1163 最高的奖励(贪心+优先队列)

题目链接:51nod 1163 最高的奖励 看着这题我立马就想到昨天也做了一道贪心加优先队列的题了奥. 按任务最晚结束时间从小到大排序,依次选择任务,如果该任务最晚结束时间比当前时间点晚,则将该任务的奖励值压入队列,否则将队列中最小的任务的奖励值替换,优先队列按奖励值小的优先. 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<queue> 5 using name

51NOD 1163 最高的奖励

来源:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1163 这个题 自己想了想 mmp 感觉一做贪心题只会用 sort 忽略了 优先队列 这题搜了题解后 大概明白了  就是建立一个最小堆  把cost 压入最小堆 如果当前时间 > Q.size() 说明可以直接加 如果小于等于 就要把cost 压入后 取一个最小的出来 挺好的一个题 #include <bits/stdc++.h> using namespa

51Nod 1083 矩阵取数问题(矩阵取数dp,基础题)

1083 矩阵取数问题 基准时间限制:1 秒 空间限制:131072 KB 分值: 5 难度:1级算法题 一个N*N矩阵中有不同的正整数,经过这个格子,就能获得相应价值的奖励,从左上走到右下,只能向下向右走,求能够获得的最大价值. 例如:3 * 3的方格. 1 3 3 2 1 3 2 2 1 能够获得的最大价值为:11. Input 第1行:N,N为矩阵的大小.(2 <= N <= 500) 第2 - N + 1行:每行N个数,中间用空格隔开,对应格子中奖励的价值.(1 <= N[i] 

51nod 1163 贪心

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1163 1163 最高的奖励 基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题 收藏 关注 有N个任务,每个任务有一个最晚结束时间以及一个对应的奖励.在结束时间之前完成该任务,就可以获得对应的奖励.完成每一个任务所需的时间都是1个单位时间.有时候完成所有任务是不可能的,因为时间上可能会有冲突,这需要你来取舍.求能够获得的最高奖励. Inp

NYIST 1107 最高的奖励

最高的奖励 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述 请问:挖掘机技术哪家强?AC了告诉你! 给你N(N<=3*10^4)个任务,每个任务有一个截止完成时间t(1=<t<=10^9)和完成该任务的奖励v(1=<v<=10^9),每个任务要花一天完成,问最多能获得多少奖励? 输入 多组 测试数据.第一行一个数N,表示任务总数.接下来N行,每行两个数t和v,如上所述. 输出 对于每组数据输出最高的奖励. 样例输入 7 4 20 2 60 4 7

51nod 1201 整数划分(dp)

题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1201 题解:显然是一道dp,不妨设dp[i][j]表示数字i分成j个一共有几种分法. 那么转移方程式为: dp[i][j] = dp[i - 1][j] + dp[i - 1][j - 1] 表示将i - 1划分为j个数,然后j个数都+1 还是不重复,将i - 1划分为j - 1个数,然后j - 1个数都+1,再加上1这个数. 然后就是j的范围要知道1+2+

BZOJ1076: [SCOI2008]奖励关

1076: [SCOI2008]奖励关 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1669  Solved: 921[Submit][Status][Discuss] Description 你正在玩你最喜欢的电子游戏,并且刚刚进入一个奖励关.在这个奖励关里,系统将依次随机抛出k次宝物, 每次你都可以选择吃或者不吃(必须在抛出下一个宝物之前做出选择,且现在决定不吃的宝物以后也不能再吃).  宝物一共有n种,系统每次抛出这n种宝物的概率都相同且

51nod 1138 连续整数的和(数学)

题目描述: http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1138 给出一个正整数N,将N写为若干个连续数字和的形式(长度 >= 2).例如N = 15,可以写为1 + 2 + 3 + 4 + 5,也可以写为4 + 5 + 6,或7 + 8.如果不能写为若干个连续整数的和,则输出No Solution. Input 输入1个数N(3 <= N <= 10^9). OutPut 输出连续整数中的第1个数,如果有多

51nod 1463 找朋友(线段树+离线处理)

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1463 题意: 思路: 好题! 先对所有查询进行离线处理,按照右区间排序,因为k一共最多只有10个,所有在该区间内的B数组,每次枚举K值,通过这样的方式来得到另外一个B值.但是这样得到的B值它在B数组中的位置必须在当前数的左边.如下图:(j为当前数在B数组中的位置,pos为计算得到的另一个B值在数组中的位置) 这两个数的和记录在pos中,这里pos的位置必须在j的左边,假