題面:ios
超市裏有N件商品,每一個商品都有利潤pipi和過時時間didi,天天只能賣一件商品,過時商品(即當天di<=0di<=0)不能再賣。c++
求合理安排天天賣的商品的狀況下,能夠獲得的最大收益是多少。測試
輸入包含多組測試用例。優化
每組測試用例,以輸入整數N開始,接下里輸入N對pipi和didi,分別表明第i件商品的利潤和過時時間。spa
在輸入中,數據之間能夠自由穿插任意個空格或空行,輸入至文件結尾時終止輸入,保證數據正確。code
對於每組產品,輸出一個該組的最大收益值。xml
每一個結果佔一行。blog
0≤N≤100000≤N≤10000,
1≤pi,di≤100001≤pi,di≤10000排序
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
這道題目,咱們很容易發現是有一個貪心性質,也就是對於t天,咱們須要在保證不賣出過時商品的前提下,賣出利潤前t大的商品.
因此呢,咱們能夠把商品按照過時時間排序,而後創建一個小根堆,對於每個數而言,若是說它的過時時間大於當前小根堆的個數,那麼咱們能夠直接將這個貨物的價值加入進來,若是說當前過時時間正好等於這個小根堆堆內的個數,那麼咱們就須要對比一下,若是說這個貨物的價值,是高於小根堆的堆頂的話,那麼咱們就將小根堆堆頂彈出,而後push咱們這個新貨物,由於新貨物明顯是更加優於堆頂的老貨物的隊列
代碼:
#include<iostream> #include<algorithm> #include<cstring> #include<queue> #include<vector> using namespace std; int main() { int n; while(cin>>n) { vector<pair<int,int> >pp(n); for(int i=0;i<n;i++) cin>>pp[i].second>>pp[i].first; sort(pp.begin(),pp.end()); priority_queue<int,vector<int>,greater<int> >head; for(auto p:pp) { head.push(p.second); if(head.size()>p.first)head.pop(); } int res=0; while(head.size())res+=head.top(),head.pop(); cout<<res<<endl; } return 0; }
法二:用並查集維護:(看的大佬的題解)
貪心策略:
在不過時的時間內優先賣出利潤更大的產品。
按照價值降序,每次掃描到一個價值,嘗試一下在過時以前能不能賣出去;此時可能已經有比它更大價值的產品佔用了一些日期,因而從過時時間往前面找,直到找到一個空位置。若是這個空位置大於0,那麼就把這個產品安排在這天賣出。
暴力找位置最壞複雜度能夠達到O(n2)O(n2),因此用並查集優化,每一個節點表明日期,日期記錄他最近的前面的空閒日期是哪天,每次用掉這天就把這個點和前面的點連起來
實測比優先隊列快了三倍
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e4 + 233;
typedef pair<int,int> pii;
vector<pii> a;
int f[maxn];
int ff(int x)
{
if(f[x] == x) return x;
return f[x] = ff(f[x]);
}
int main()
{
int n;
while(cin >> n)
{
int ans = 0;
a.clear();
int maxe = 0;
for(int i = 1; i <= n; i++)
{
int v,e;
scanf("%d%d", &v, &e);
a.push_back({-v, e});
maxe = max(maxe, e);
}
for(int i = 0; i <= maxe; i++) f[i] = i;
sort(a.begin(), a.end());
for(int i = 0; i < a.size(); i++)
{
int v = -a[i].first, e = a[i].second;
int pos = ff(e);
if(pos > 0)
{
ans += v;
f[pos] = pos - 1;
}
}
printf("%d\n", ans);
}
}
做者:米4達girl連接:https://www.acwing.com/solution/acwing/content/1350/來源:AcWing著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。