贪心——「一本通 1.1 例 5」智力大冲浪

「一本通 1.1 例 5」智力大冲浪

一、题目描述

题目链接

二、解题思路

用官方的词语解释:这是一个带期限和罚款的单位时间任务调度的问题,需要使用贪心。
其实带期限和罚款的单位时间任务调度问题是有时间期限罚款(奖励),的一类问题,要求解的是在区间时间段内所能够达到的最多的奖励(最少的罚款)
这虽然是一个最优子结构的问题,但是也可以使用贪心来求解。

【贪心策略】

1、排序

因为要求解最少数量的罚款,那么就一定要先解决罚款数量多的项目。为了方便起见,可以先把罚款的金额从大到小排序。这样,就可以直接顺序处理了。

2、安排时间

因为有些项目只能在很短的时间期限内完成,但如果一开始就占据了那个时间,那么,这一个项目就无法完成,所以,任何一个项目都要一最玩的时间去完成,所以可以宜采用倒着循环来解决这个问题。但是如果怎么都不能做这一个项目,则放弃这个项目

3、计算答案

因为题目要求的是最多得到的钱的数量,则可以一开始可以定义一个变量ans来记录最多可以得到的钱的数量,每一次放弃一个项目,ans都减去“罚款”,这样就能计算出最后的解了。

三、代码

#include
#include
#include
#include
using namespace std;
const int N=1010;
int m,n,Time[N],ans;//m表示一开始给参赛者的钱数,Time表示时间轴,ans表示能获得的最多的钱 
struct node{
	int time,cost;
}race[N]; 
bool Cmp(node a,node b)
{
	return a.cost>b.cost;//按照惩罚从大到小排序
} 
void init()//输入 
{
	scanf("%d%d",&m,&n);
	ans=m;
	for(int i=1;i<=n;i++)
		scanf("%d",&race[i].time);
	for(int i=1;i<=n;i++)
		scanf("%d",&race[i].cost);
	sort(race+1,race+1+n,Cmp);
}
void solve()
{
	memset(Time,-1,sizeof(Time));
	bool ok;
	for(int i=1;i<=n;i++)
	{
		ok=false;
		for(int j=race[i].time;j>=1;j--)//尽量放在后面做 
		{
			if(Time[j]==-1)//若果这个位置没有被占用 
			{
				Time[j]=i;
				ok=true;
				break;
			}
		}
		if(ok==false)
			ans-=race[i].cost;
	}
	printf("%d",ans);
}
int main()
{
	init();
	solve();
	return 0;
}

你可能感兴趣的:(贪心)