思路
贪心思路解题,每次都选局部最优值。
(1)先将所有的商品按照过期时间排序;
(2)创建一个集合S,然后遍历每一件商品:
- 将商品加入 S 中;
- 如果当前S中的商品数目超过了能卖的数量(S中的最大天数),则将利润最小的商品从S中删除;
(3)最后S中剩下的即为满足过期条件且能使得利润最大的商品。
注意:
每次需要从S中删除利润最小的商品,因此S用最小堆实现。
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
#define x first
#define y second
typedef pair<int,int> PII; //存 过期天数-利润
int main()
{
int n;
while(cin>>n)
{
vector<PII> prod(n); //初始化长度为n的vector
for(int i=0; i<n; i++) cin >> prod[i].y >> prod[i].x;
sort(prod.begin(),prod.end()); //根据商品的过期时间排序,pair<>默认先使用first排序
priority_queue<int, vector<int>, greater<int>> heap; //堆中存放商品的利润值即可
for(auto p : prod)
{
heap.push(p.y); //利润值入堆
if(heap.size() > p.x) heap.pop(); //堆中商品数量超过能卖的天数,则将价值最低的商品出堆
}
int res = 0;
while(heap.size())
res += heap.top(), heap.pop();
cout<<res<<endl;
}
return 0;
}