2020年“远光杯”粤澳计算机程序设计大赛网络资格赛K题详解及一些拓展想法

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的两种先后顺序进行分析。

在这里插入图片描述
很明显,两者总时间是一样的,可以看到先讲的时间长的情况下,虽然是比较后才开始做,但是后面出现二者重叠的情况总长度因此减少,这里就是我刚刚提到的重点,因为做的时间不是简单的叠加的,而是取最大值,所以对于这道题来说,并不需要讨论老师讲的时间,但如果题目中是学生一次只能完成一项任务的话,那么这个讲的时间也需要考虑在内了。

最后,这些是我做这道题的一些想法,希望对大家的学习有帮助,本人还是一位萌新,还望大佬指点。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值