upc Leopard学霸#堆+贪心

问题 C: Leopard学霸
时间限制: 1 Sec 内存限制: 128 MB

题目描述
马上假期就要到了,THU的神犇Leopard假期里都不忘学霸,现在有好多门功课,每门功课都耗费他1单位时间来学习。 他的假期从0时刻开始,有1000000000个单位时间(囧rz)。在任意时刻,他都可以任意一门功课(编号1~n)来学习。 因为他在每个单位时间只能学习一门功课,而每门功课又都有一个截止日期,所以他很难完成所有n门功课。 对于第i门功课,有一个截止时间Di,若他能学完这门功课,他能够获得知识Pi。 在给定的功课和截止时间下,Leopard能够获得的知识最多为多少呢?
输入
第一行,一个整数n,表示功课的数目 接下来n行,每行两个整数,Di和Pi

输出
输出一行一个整数,表示最多学得的知识数
样例输入 Copy
3
2 10
1 5
1 7
样例输出 Copy
17
提示
样例说明:第一个单位时间学习第3个功课(1,7),然后在第二个单位时间学习第1个功课(2,10)
【数据范围】
10%数据满足:n<=25
60%数据满足:n<10000
100%数据满足:1<=n<=100000,Di、Pi<=1000000000 最后的答案可能超过32位整型。

看一下蒟蒻的代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#define INF 0x3f3f3f3f
priority_queue<int,vector<int>,greater<int> >q1;
priority_queue<int,vector<int>,less<int> >q2;
const int maxn = 1e5 + 7;
const int mod = 1e9 + 7;
/** keep hungry and keep calm! **/

ll ans;
int n,t;
struct node
{
	int x;
	int y;
}a[100005];

bool cmp(node a,node b)
{
	return a.x < b.x;
	//按截止时间升序排列 
}

int main()
{
	cin >> n;
	for(int i=1;i<=n;i++)
	{
		cin >> a[i].x >> a[i].y;
	}
	sort(a+1,a+1+n,cmp);
	/**
	1 5
	1 7
	2 10
	**/
	for(int i=1;i<=n;i++)
	{
		if(t < a[i].x)
		{
			t++;
			ans += a[i].y;
			q1.push(a[i].y);
		}
		else if(q1.top() < a[i].y)
		//说明当前不是最大知识数
		{
			ans = ans - q1.top() + a[i].y;
			//把最小知识数的功课踢掉
			q1.pop();//把之前队列元素删除
			q1.push(a[i].y);//加入比之前大的数
		}
		/**
		模拟两次循环
		t初值为0,t < a[1].d=1 所以t++
		ans = a[0].p = 5 
		把a[0].p = 5放进队列
		t = 1  a[1].d = 1 所以跳到else if
		队顶元素比a[1].p小,说明不是最优解,ans把之前的队顶元素减掉然后加上当前的值
		删除之前的队顶元素
		将现在的最大值放到队列中
		**/ 
	}
	cout << ans << endl;
	return 0;
}
发布了54 篇原创文章 · 获赞 0 · 访问量 1144

猜你喜欢

转载自blog.csdn.net/magic_wenge/article/details/104881251
UPC