家庭作业(贪心+并查集)

家庭作业(贪心+并查集)

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

每个作业的完成时间都是只有一天。例如,假设有 7 次作业的学分和完成时间如下:

在这里插入图片描述

最多可以获得 15 学分,其中一个完成作业的次序为 2,6,3,1,7,5,4注意可能还有其他方法。

你的任务就是找到一个完成作业的顺序获得最大学分。

【输入格式】

第一行一个整数 N,表示作业的数量;

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

【输出格式】

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

【样例输入】
7
1 6
1 7
3 2
3 1
【样例输出】
15

思路: 数据太大,暴力就不好使了,这里引入并查集来解决问题,f[i]=x,表示第i天前面最大的能用的一天为第x天,x这一天被用之后,就要更新f[i],那就找第x-1天前最大能用的为第几天放入f[i]中

AC代码:

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int book[1100000],f[1100000];
struct pp
{
	int a,b;
}p[1100000];
bool cmp(pp x,pp y)
{
	return x.b>y.b;
}
void init()
{
	for(int i=0;i<=1100000;i++)
	f[i]=i;//初始第i天前最大能用的为本身
}
int find(int x)//并查集
{
	if(f[x]==x)
	return x;
	return f[x]=find(f[x]);
}
int main()
{
	int n,i,j,k;
	init();
	scanf("%d",&n);
	for(i=0;i<n;i++)
	scanf("%d%d",&p[i].a,&p[i].b);
	sort(p,p+n,cmp);
	int sum=0;
	for(i=0;i<n;i++)
	{
		int xx=find(p[i].a);//p[i].a前能用的最大为第xx天
		if(xx)//xx存在,即p[i].a前还有天可用
		{
			sum+=p[i].b;//加学分
			int yy=find(xx-1);//找xx前一天能用的为第几天
			f[xx]=yy;//更新
		}
	}
	printf("%d\n",sum);
	return 0;
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值