题目链接:Commando War
直觉告诉我们,执行时间较长的任务应该先交代。于是想了一个贪心算法:按照 J 从大到小给各个任务排序,然后依次交代。
那么为什么这样做是对的呢?假设我们交换相邻的任务 X 和 Y(交换前 X 在 Y 之前,交换后 Y 在 X 之前),不难发现其他任务的完成时间没有影响。对于这两个任务而言,有两种情况:
情况一 :交换之前,任务 Y 比 任务 X 先结束,不难发现,交换之后 X 的结束时间延后,Y 的结束时间提前,最终答案不会变好。
情况二 :交换之前,任务 X 比 任务 Y 先结束,因此结束后不会变好的充要条件是:交换后 X 的结束时间不比交换前 Y 的结束时间早(交换后 Y 的结束时间肯定变早了),所以这个条件可以写成 b[y] + b[x] + j[x] >= b[x] + b[y] + j[y] 化简得 j[x] >= j[y]。这就是贪心的依据。
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
struct Node{
int b;
int j;
}e[10010];
int n;
bool cmp(Node a,Node b){
return a.j > b.j;
}
int main()
{
int kase = 1;
while(scanf("%d",&n) && n){
for(int i=1;i<=n;i++){
scanf("%d%d",&e[i].b,&e[i].j);
}
sort(e+1,e+1+n,cmp);
int ans = 0;
int s = 0;
for(int i=1;i<=n;i++){
s += e[i].b;
ans = max(ans,s+e[i].j);
}
printf("Case %d: %d\n",kase ++,ans);
}
return 0;
}