最高的奖励

Problem Description

中文:有N个任务,每个任务有一个最晚结束时间以及一个对应的奖励。在结束时间之前完成该任务,就可以获得对应的奖励。完成每一个任务所需的时间都是1个单位时间。有时候完成所有任务是不可能的,因为时间上可能会有冲突,这需要你来取舍。求能够获得的最高奖励。

English:There are N tasks, each with a latest end time and a corresponding bonus. By completing the task before the end time, you can get the corresponding reward. The time required to complete each task is 1 unit time. Sometimes it is impossible to complete all tasks, because there may be conflicts in time, which requires you to choose. Seek the highest reward you can get.

Problem Analysis

中文:这是关于贪婪算法的问题,我们要确保最后的奖励最大化。

  首先,我们从第一个时间开始考虑的话,按这个例子来说,我们将面临全部的选择;之后选择依旧很多,让人无法合理的切入问题。

  因此,我们就要换个思路。从最后一个时间来考虑,在最后一个时间的可完成任务中选择出最大奖励的任务。同时,也是很重要的,我们应该把选择的最大奖励的任务的奖励置为0,。防止在之后的选择最大奖励任务的步骤中,对后面任务的正常选择造成影响。之后,只需在从后到前的每个时间里,选择出最大奖励的任务。重复上面的步骤。

English: This is a question about greedy algorithms, we want to ensure that the final reward is maximized.

First of all, if we consider it from the first time, according to this example, we will face all the choices; after that, there are still many choices, which makes it impossible to cut into the problem.

Therefore, we have to change our minds. From the last time, consider the task of selecting the maximum reward in the last completed task. At the same time, it is also very important that we should set the reward for the task of the largest reward selected to 0. Prevents the subsequent selection of the maximum reward task from affecting the normal selection of subsequent tasks.After that, you only need to select the task with the most rewards in each time from back to front. Repeat the above steps.

Standard Input

Line 1: A number N, indicating the number of tasks (2 <= N <= 50000)
Line 2 - N + 1, 2 lines per line, separated by spaces, indicating the latest end time E[i] of the task and the corresponding reward W[i]. (1 <= E[i] <= 10^9,1 <= W[i] <= 10^9)

Standard Output

Output the highest reward you can get.

Input Sample

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

Output Sample

230

Code

#include <iostream>
#include <stdio.h>
#include <algorithm>
using namespace std;
//定义一个结构体存储数据
struct Task
{
    long long end_time;
    long long reward;
};
//结束时间由小到大的比较函数
bool compare(Task a, Task b)
{
    return a.end_time<b.end_time;
}
int main()
{
    struct Task t[50001];
    long long number;
    cin>>number;//输入任务的数量
    for(int i=0;i<number;i++)
        cin>>t[i].end_time>>t[i].reward;//输入结束时间和对应奖励
    sort(t,t+number,compare);//按时间进行排序
   /*检验按时间排序是否正确
   for(long long i=0;i<number;i++)
        cout<<t[i].end_time<<"  "<<t[i].reward<<endl;*/
    long long total=0,max_reward,max_rewards;
    for(long long m=number;m>=1;m--)
    {
        max_reward=0;//定义一个最大奖励
        max_rewards=number+1;//记录最大奖励的下标
        for(long long j=number-1;j>=0;j--)
        {
            if(t[j].end_time<m)break;//任务结束时间比最长时间早导致任务无法完成 跳出
            if(t[j].reward>max_reward)//在所有可完成任务中选出最大奖励
            {
                max_reward=t[j].reward;
                max_rewards=j;
            }
        }
        total+=max_reward;  //选出可获得最大奖励的任务后,对其奖励进行相加,经循环后得到最多的奖励
        t[max_rewards].reward=0;//选出一个最大奖励要对其值重置为0;以免影响后面最大奖励的选择
    }
   cout<<total<<endl;
    return 0;

}

Result

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值