K —— 项目管理
题目内容:
- GM老师有n个学生,每个学生需要完成一个项目。GM老师需要花Mi分钟为第i个学生布置任务,然后这个学生会独立不间断的用Ri分钟完成项目。请问GM老师需要选择怎样的顺序来布置任务,才能使得所有项目尽早执行完(也就是最后一个完成的学生尽快结束)。注意,GM老师不能同时给两个学生布置项目,但学生可以同时执行他们各自的项目。
输入要求:
-
输入n+1行
第1行输入项目数n
第2行到n+1行,每行输入GM老师为这n个学生布置任务所需时间M和完成任务所需时间R
所有输入均为整数,其取值范围为[1, 1000]
输出要求:
-
输出项目个数和所有项目完成的最短时间(分钟),格式如下:
Project n: m(其中,n代表项目个数,m代表最短时间,注意有换行)
详见输出样例
输入输出样例:
样例一:
输入
3
3 6
4 3
3 2
输出
Project 3: 12
样例二:
输入
4
5 5
6 6
7 7
8 8
输出
Project 4: 31
思路:
这道题题意就是老师边讲任务,学生边做任务,但是学生要老师讲完后才能做,求最少用时。很明显,是一道贪心的题目,所以要让做任务时间长的学生先开始任务,这样老师讲的时候学生可以同时做前面用时较长的任务。如果不能理解的话,尝试反过来,先让做任务时间短的开始,那么比前一种更多(因为前一种思路也会出现)可能出现,下个任务还没讲完,而上个任务就已经结束的情况。
这是只是最佳排序的方法,然而他是要求算出时间,那么怎么计算时间呢?
首先,因为是要先讲才能做,所以无论怎么做,讲的时间必然不可能少,所以最后的时间里一定包含所有讲的时间。那么问题来了,怎么算讲完还在做的时间。我们可来通过样例分析。
比如第一个样例,按照我们的最佳排序,所以我们先讲3(直接用数字表示时间),然后讲完后才开始做6,但是注意做6和讲4是同时开始的,所以等我们讲完4的时候,做6其实已经完成了4了,所以上一个任务剩下2,那么剩2和做3怎么处理呢,我们要取最大值(这个很重要,也是我后面拓展的关键),因为题目写学生是各自完成自身任务,因此其实在做3的过程剩2已经完成了。
所以,时间的计算方法就出来了,总时间 = 讲的总时间 + max(上一任务做剩的时间,本任务做的时间)
代码:
#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
struct student{
int talk,done;
};
bool cmp(student a,student b){
return a.done > b.done;
}
int main(){
vector<student> all;
int n;
cin >> n;
for(int i = 0;i < n;i++){
student in;
cin >> in.talk >> in.done;
all.push_back(in);
}
sort(all.begin(),all.end(),cmp);
vector<student>::iterator number;
number = all.begin();
int alltime = (*number).talk,dotime = (*number).done;
for(number = all.begin() + 1;number != all.end();number++){
alltime += (*number).talk;
int elsetime = dotime - (*number).talk;
if(elsetime < 0) elsetime = 0;
dotime = max(elsetime,(*number).done);
}
printf("Project %d: %d\n",n,alltime + dotime);
return 0;
}
拓展:
题目的思路大致于此,但后面我在做题的时候,突然有一个疑问,那么在做的时间一样的情况下,老师讲的时间需不需要也排序呢?我当时是想如果做的时间一样,讲的时间少的任务先讲完,那么不是会先开始做任务,这样不是压缩时间了吗?
但是经过实操之后,我发现是不管是否排序讲的时间结果都是一样的,我对此不解。但后面我想到用时间轴的方式来解决这个疑惑。
我们用例子 4 5 和 6 5的两种先后顺序进行分析。
很明显,两者总时间是一样的,可以看到先讲的时间长的情况下,虽然是比较后才开始做,但是后面出现二者重叠的情况总长度因此减少,这里就是我刚刚提到的重点,因为做的时间不是简单的叠加的,而是取最大值,所以对于这道题来说,并不需要讨论老师讲的时间,但如果题目中是学生一次只能完成一项任务的话,那么这个讲的时间也需要考虑在内了。
最后,这些是我做这道题的一些想法,希望对大家的学习有帮助,本人还是一位萌新,还望大佬指点。