题目
CTG(Cun Tou Gaming) 是我校的一支 LOL 战队,他们参加比赛总是可以拿到冠军,因为每次都只有他们一支队伍参赛,所以只需要去签个到就可以直接夺冠并领取奖金。现在有 n 场比赛可以让他们选择,每场比赛都有各自的截止日期 d 和奖金 r ,而 CTG 战队必须在截止日期之前(包括截止日期当天)去参赛才可以拿到奖金。由于签到是一项很辛苦的工作所以战队一天只能参加一场比赛。现在要你设计出一种参赛方案,使他们可以拿到最多的奖金。
Input
有多组样例,第一行一个整数 T(T≤10),表示 T组样例,对于每组样例:
第一行给出一个整数 n表示有 n(n≤105)场比赛可以参加。
接下来的 n行,每行由 d 和 r 组成 (d,r≤109),分别表示截止日期和奖金数。
Output
输出 T行。
每行即为该组测试中可以拿到的最多奖金数,保证答案在long long int的范围内。
Examples
Input
2
3
2 10
2 15
3 20
3
2 10
1 50
1 40
Output
45
60
解析:这道题目其实是一道非常水的题目,但是我还是太菜了,比赛的时候一眼觉得是一个贪心,但是由于数据量太大,不能暴力的贪心,所以觉得无从下手,但是只要稍微转一个弯,我们对日期进行贪心,然后有优先队列选出当前需要的最大的那个就可以了
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include<cmath>
#include<set>
#include<list>
#include<deque>
#include<map>
#include<queue>
using namespace std;
typedef long long ll;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int INF = 0x3f3f3f3f;
const long long inf =1e18;
const int maxn = 1e5+50;
const int mod =1e9+7;
int T,n,m;
struct node
{
ll d,r;
bool operator <(const node &oth)const
{
return r<oth.r;
}
};
node sh[maxn];
bool cmp(node a,node b)
{
return a.d>b.d;
}
int main()
{
scanf("%d",&T);
while(T--)
{
ll ans=0;
scanf("%d",&n);
for(int i=1; i<=n; i++)
{
scanf("%lld%lld",&sh[i].d,&sh[i].r);
}
sort(sh+1,sh+1+n,cmp);
// for(int i=1;i<=n;i++)
// {
// printf("%lld ",sh[i].d);
// }
priority_queue<node>pq;
int day=sh[1].d;
for(int i=1; i<=n; i++)
{
if(sh[i].d>=day)
{
pq.push(sh[i]);
}
else
{
if(!pq.empty())
{
ans+=pq.top().r;
pq.pop();
}
day--;
i--;
//cout<<day<<endl;
}
}
while(day)
{
if(!pq.empty()&&pq.top().d>=day)
{
ans+=pq.top().r;
pq.pop();
}
day--;
}
printf("%lld\n",ans);
}
return 0;
}