【题目】
【输入输出要求】
【样例】
【程序代码】
<span style="font-family:Microsoft YaHei;font-size:18px;">#include<stdio.h>
#include<algorithm>
#define N 10000
struct soldiers//定义士兵信息的结构体
{
int b;//讲述任务的时间
int j;//执行任务的时间
}task[N];
int cmp(soldiers x,soldiers y) //将执行任务的时间按照从大到小的顺序排列
{
if(x.j > y.j)
return 1;
return 0;
}
int main()
{
int n,t=1;
while(scanf("%d",&n)&&n)
{
for(int i=0;i<n;i++)//输入n组士兵的相关信息
scanf("%d%d",&task[i].b,&task[i].j);
std::sort(task,task+n,cmp);//根据士兵执行工作的时间从大到小排列
int total=0;//记录要花费的时间
int sum=0;
for(int i=0;i<n;i++)
{
sum +=task[i].b;//士兵讲述任务所需时间
//如果之前讲述任务和执行任务的时间足以覆盖此次任务
total=std::max(total,sum+task[i].j);//在讲述任务与接下来任务执行所花时间,和之前已经花时间之间选择最大值
}
printf("Case %d: %d\n",t++,total);
}
}
</span>
【简要分析】
就题目本身而言,突击战问题中,提到当给一个士兵讲述任务的时候,另外一个士兵是可以去执行任务的,但是任务的执行必须是在讲述完之后,要想使得总共所花的时间最短,那么要求讲述和执行任务的时间尽可能的多,将士兵执行任务的时间按照长短大小排列,第一个任务的讲述时间必然是算在总时间里的,接下来,就拿第一个任务讲述和执行所花的时间与第一个任务讲述和第二个任务讲述和执行所花的时间进行比较,如果前者大,说明,在第一个任务执行的时间大于或者等于第二个任务讲述和执行的时间,此时两个任务完成的时间就是第一个任务完成的时间,如果后者大,说明还要花额外的时间等候第二个任务完成,任务完成时间即就是后者。(难以理解的话,可以看成一个数学表达式,两个表达式求最大值,两者有相同部分,不同的部分大的即为最大)以此类推,直至所有任务完成。所以第一个完成的任务应该是执行时间最长的,以保证,覆盖时间最长。
这其实也是一个贪婪问题,如同上一道题,每一个任务都要完成,我要求得总时间最少,那么要使得每一个任务所花的时间尽量少,那么就要求覆盖时间尽量多,每一步最优,结果才最优,再次提到sort排序。