【堆】B002_AW_超市(貪心+最小堆)
阿新 • • 發佈:2020-09-09
超市裡有N件商品,每件商品都有利潤pi和過期時間di,每天只能賣一件商品,過期商品不能再賣。
求合理安排每天賣的商品的情況下,可以得到的最大收益是多少。
輸入格式
輸入包含多組測試用例。
每組測試用例,以輸入整數N開始,接下來輸入N對pi和di,分別代表第i件商品的利潤和過期時間。
在輸入中,資料之間可以自由穿插任意個空格或空行,輸入至檔案結尾時終止輸入,保證資料正確。
輸出格式
對於每組產品,輸出一個該組的最大收益值。
每個結果佔一行。
資料範圍
0≤N≤10000,
1≤pi,di≤10000
最多有14組測試樣例
輸入樣例: 4 50 2 10 1 20 2 30 1 7 20 1 2 1 10 3 100 2 8 2 5 20 50 10 輸出樣例: 80 185
方法一:貪心+小根堆
每天只能賣出一種商品,首先時間得有序才能再對利潤做出決策,這裡先對時間升序排序;當遇到新商品 x 時,且第 j 天能賣的商品個數已經達到了 j 個(即加入該商品後是j+1個),那麼就對比商品 x 和這 1~j 天中利潤最小的商品的利潤,如果 x.p 大於它,那麼這個商品就不要了了
#include<bits/stdc++.h> using namespace std; typedef long long ll; struct node{ ll p, d; }; bool cmp(const node &a, const node &b){ return a.d < b.d; } const int N=1e5+5; node A[N]; int main() { std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int n; while (cin>>n) { for (int i=0; i<n; i++) cin>>A[i].p>>A[i].d; priority_queue<ll, vector<ll>, greater<ll>> minQ; sort(A, A+n, cmp); for (int i=0; i<n; i++) { minQ.push(A[i].p); if (minQ.size()>A[i].d) { minQ.pop(); } } int ans=0; while (!minQ.empty()) { ans+=minQ.top(); minQ.pop(); } cout << ans << '\n'; } return 0; }
複雜度分析
- Time:\(O(nlogn)\),
- Space:\(O(n)\),