家庭作业-贪心算法

题目:

老师在开学第一天就把所有作业都布置了,每个作业如果在规定的时间内交上来的话才有学分。每个作业的截止日期和学分可能是不同的。例如如果一个作业学分为 10,要求在 6 天内交,那么要想拿到这 10 学分,就必须在第 6 天结束前交。

每个作业的完成时间都是只有一天。

输入

第一行一个整数N,表示作业的数量;
接下来N行,每行包括两个整数,第一个整数表示作业的完成期限,第二个数表示该作业的学分。

输出

输出一个整数表示可以获得的最大学分。保证答案不超过 C/C++ 的 int 范围。

范围:

 思路:

如果仅仅按照时间的紧迫程度来排列,那么有些情况就会不符合最优情况,如

4

1 3

2 4

3 9

3 8

该情况按时间排序的学分为16,但实际最大学分为21。

要满足最优解,既要看时间的紧迫程度,又要看一次学分的数值。

我们要做的就是尽量把学分大的作业在它的时间限制之内完成,如果有空余再去完成学分少的作业,而完成学分大的作业时也要满足从后往前的原则,这样才能有更多的空余给那些时间紧迫但学分少的作业留出时间完成。

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct work{
	int day;int fen;
}w[1000006];
bool cmp(work x,work y){
return x.fen>y.fen;
	
}
int b;//优化算法时间所用,用来记录从1~b已经都有安排了,不能再安排任务,
如果时间比它小需要直接跳过不再考虑
int d[800000];int ans;
int main()
{int n;cin>>n;
for(int i=0;i<n;i++){
	scanf("%d%d",&w[i].day,&w[i].fen);
	
}//输入数据
sort(w,w+n,cmp);//按照学分从大到小排序
for(int i=0;i<n;i++){
	if(w[i].day<=b)continue;//跳过的情况
	for(int j=w[i].day;j>0;j--)//从后往前挨个考虑
{
		if(d[j]==0)//该天没有安排任务的情况下
{d[j]=1;ans+=w[i].fen;//把该天计算入学分之内
		break;//已经安排好了,跳出循环}
	if(j==1)	b=w[i].day;//到最后仍然没有位置了,说明从1~b已经排满,记录该种情况
	}
	
	
}
cout<<ans;


return 0;

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值