Link
话说最近怎么老是切这么水难的题目
Solve
题面和以前做过的一道题一样:智慧大冲浪
熟悉吗,嘻嘻嘻
法一(堆)
以结束时间从小到大排序,贪心地选择当前天数t能卖出的最有价值的t个商品,用小根堆维护,复杂度(O(NlogN))
法二(并查集)
考虑另一种贪心思路:以价值从大到小排序,考虑先卖出价值大的商品,并且对于每个商品都在过期前尽可能晚卖掉,即占用较晚的时间。显然对于某一个商品,将时间调前,答案不会更优
可以用并查集维护日期的占用情况
Code
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define Maxn 10010
using namespace std;
struct point{
int a=0,b=0;//a:Pi,收益;b:Di,过期时间;
}p[Maxn];
//建立结构体。
bool cmp(point a1,point b1)
{
if(a1.b==b1.b)
return a1.a>b1.a;//Di相等,就将Pi降序排列
else
return a1.b<b1.b;//Di不等,就将Di升序排列
}
/*排序用到的主要思想是:
1、一天只能卖一件商品,当然挑价值最高的卖;
2、过期时间短的先卖,长的后卖;
*/
int main()
{
int n,sum;
while(cin>>n){
memset(p,0,sizeof(p));
sum=0;
//每一次做完后要把数组与sum清零;
for(int i=1;i<=n;i++){
cin>>p[i].a>>p[i].b;
}
/*输入;
这儿有一个小技巧,
把数组第一个值留空,
方便之后去重;
*/
sort(p,p+n+1,cmp);
//排序
for(int i=1;i<=n;i++){
if(p[i].b!=p[i-1].b){
sum+=p[i].a;
}
//数组去重;
}
//过期时间相同时,取收益最大的卖;
cout<<sum<<endl;
//结果按行输出;
}
return 0;
}