1. 程式人生 > >HDU6438:Buy and Resell(貪心+數據結構)

HDU6438:Buy and Resell(貪心+數據結構)

ace mes 多少 queue nbsp space 當前 ron 等於

題意 : 給出一些數、你可以從左到右對這些數進行三種操作花費 Ai 買入東西、以 Ai 價格賣出你當前有的東西、或者什麽都不做、現在問你可以獲取的最大利益是多少

分析:對每一個元素產生的貢獻可以先計算出暫時的最優值,註意是暫時的最優,應為後面可以出現更加優的答案,所有下次遇到更優的時候就進行替換;

具體就是首先使用小頂堆維護枚舉過的元素

然後對於當前枚舉到的元素

用它和堆頂元素做對比、如果小於或等於堆頂元素

那麽它無法和之前枚舉過的所有元素的任何一個做減法產生貢獻

所以將其加入這個小頂堆當中去

如果大於堆頂元素、則用它和堆頂元素做減法、算出它和堆頂元素產生貢獻

當然這個貢獻只是暫時最優的、堆頂元素和當前枚舉到的元素進行配對並不一定是最優的

那麽怎麽樣在下一次枚舉到更優的配對元素時進行替換

答案就是做完貢獻之後、將堆頂元素彈出、然後 push 兩次當前枚舉到的元素進入堆內

第一個 push 的意義是下次如果其作為堆頂元素、那麽可以把它拿出來做減法達到反悔操作

第二個 push 的意義就是真正的賣出

每天都賣出,每次累加差值就可以了。累加很多個差分值肯定會得到最優解的。
?因為A買入B賣出B買入C賣出 和 A買入C賣出 效果一樣的

技術分享圖片
#include<bits/stdc++.h>
using namespace std;
#define pll pair<long long , long long >
#define
ll long long int main( ) { int t ; scanf("%d",&t); while(t--) { int n ; scanf("%d",&n); priority_queue<pll , vector<pll> , greater<pll> > qu ; ll ans = 0 ; int num = 0; for(int i=0 ; i<n ; i++) { ll val; scanf(
"%lld",&val); if(!qu.empty() && qu.top().first < val) { num++; pll T=qu.top() ; qu.pop(); if(T.second == 1) num--; else num++; ans+=val-T.first; printf("(%lld %d %d)\n", ans,num,val); qu.push(make_pair(val,1)); qu.push(make_pair(val,2)); } else qu.push(make_pair(val,3)); } printf("%lld %d\n",ans , num); } }
View Code

HDU6438:Buy and Resell(貪心+數據結構)