任务描述
本关任务:小张最近很忙,记事本里有n件事情等待处理,每件事处理完毕后,能得到不同的奖励,而且都有一个截止日。一件事处理需要一整天
时间,并且小张不能同时干其他事情。请你替小张安排一个事情处理的时间表,争取获得最大的奖励。
相关知识
贪心算法。
测试说明
平台会对你编写的代码进行测试:
测试输入:第一行输入整数n,表示n个事情。随后输入n行,每行包括一个事情的截止日(不大于n)和处理收益。
测试输出:输出最大的总收益。
例 测试输入:
5 2 5
2 7
2 6
2 8
3 3
预期输出:
18
解析:
核心思路是在同样的截止日期的选项里面,选出收益最高的那一个。即在期限的约束下,按收益的高低进行选择。
#include<stdio.h>
struct project{ # 定义结构体
int deadline; // 期限
int money; // 报酬
};
int main(){
int n;
scanf("%d", &n);
project list[1000]; // 结构体数组,存储n件事情
int lastDay = 0;
int salary[1000] = {0}; // 存储第i天完成任务获得的报酬
for(int i=1; i<=n; i++){
scanf("%d %d", &list[i].deadline, &list[i].money);
if(list[i].deadline > lastDay){
lastDay = list[i].deadline; // 找出最大期限
}
}
project temp; // 中间变量
for(int i=1; i<n; i++){ // 排序,将事件按报酬从大到小排列
for(int j=1; j<n-i; j++){
if(list[j].money < list[j+1].money){
temp = list[j];
list[j] = list[j+1];
list[j+1] = temp;
}
}
}
for(int i=1; i<=n; i++){
if(salary[list[i].deadline] == 0){ // 如果在最后期限那一天没有被安排,就直接安排,因为报酬是从大到小的,所以安排的是报酬最大的。
salary[list[i].deadline] = list[i].money;
}
else{ // 如果那一天安排了,就往前面排,报酬大的能放就放。
for(int j=list[i].deadline - 1; j>=1; j--){
if(salary[j] == 0){
salary[j] = list[i].money;
break;
}
}
}
}
int sum = 0;
for(int i=1; i<=lastDay; i++){ // 将每一天的最大报酬相加即可得到最大的报酬总和
sum += salary[i];
}
printf("%d\n", sum);
return 0;
}