HDU 6438 Buy and Resell

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/tianwei0822/article/details/82083649

题目:点击打开链接

题意:给出 n ,表示 n 天。给出 n 个数,a[i] 表示第 i 天,物品的价格是多少。每天可以选择买一个物品,或者卖一个已有物品,也可以什么都不做,问最后最大能赚多少钱,最少操作次数是多少?

分析:贪心好题!cf原题(CodeForces - 867E),对每一个元素产生的贡献可以先计算出暂时的最优值,注意是暂时的最优,应为后面可以出现更加优的答案,所有下次遇到更优的时候就进行替换;具体就是首先使用小顶堆维护枚举过的元素,然后对于当前枚举到的元素,用它和堆顶元素做对比、如果小于或等于堆顶元素,那么它无法和之前枚举过的所有元素的任何一个做减法产生贡献,所以将其加入这个小顶堆当中去,如果大于堆顶元素、则用它和堆顶元素做减法、算出它和堆顶元素产生贡献,当然这个贡献只是暂时最优的、堆顶元素和当前枚举到的元素进行配对并不一定是最优的,那么怎么样在下一次枚举到更优的配对元素时进行替换,答案就是做完贡献之后、将堆顶元素弹出、然后 push 两次当前枚举到的元素进入堆内,第一个 push 的意义是下次如果其作为堆顶元素、那么可以把它拿出来做减法达到反悔操作,第二个 push 的意义就是真正的卖出,每天都卖出,每次累加差值就可以了。累加很多个差分值肯定会得到最优解的,因为A买入B卖出B买入C卖出 和 A买入C卖出 效果一样的。照着代码手推几组样例就明白了。

代码:

#pragma comment(linker, "/STACK:102400000,102400000")
#include<unordered_map>
#include<unordered_set>
#include<algorithm>
#include<iostream>
#include<fstream>
#include<complex>
#include<cstdlib>
#include<cstring>
#include<cassert>
#include<iomanip>
#include<string>
#include<cstdio>
#include<bitset>
#include<vector>
#include<cctype>
#include<cmath>
#include<ctime>
#include<stack>
#include<queue>
#include<deque>
#include<list>
#include<set>
#include<map>
using namespace std;
#define pt(a) cout<<a<<endl
#define debug test
#define mst(ss,b) memset((ss),(b),sizeof(ss))
#define rep(i,a,n) for (int i=a;i<=n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
#define ll long long
#define ull unsigned long long
#define pb push_back
#define mp make_pair
#define inf 0x3f3f3f3f
#define eps 1e-10
#define PI acos(-1.0)
typedef pair<int,int> PII;
const ll mod = 1e9+7;
const int N = 1e6+10;

ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);}
ll qp(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
int to[4][2]={{-1,0},{1,0},{0,-1},{0,1}};

int t,n,a[N];

int main() {
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    cin>>t;
    while(t--) {
        map<int,int> ma;
        priority_queue<int,vector<int>,greater<int> > q;
        cin>>n;
        ll ct=0,ans=0;
        rep(i,1,n) {
            cin>>a[i];
            if(!q.empty() && q.top()<a[i] ) {
                int x=q.top();
                q.pop();
                ans += a[i]-x,ct++;
                if(ma[x]) ma[x]--,ct--;
                ma[a[i]]++,q.push(a[i]);
            }
            q.push(a[i]);
        }
        cout<<ans<<" "<<2*ct<<endl;
    }
    return 0;
}

参考博客:http://www.cnblogs.com/shuaihui520/p/9537511.html

猜你喜欢

转载自blog.csdn.net/tianwei0822/article/details/82083649
今日推荐