Buy Low Sell High CodeForces - 865D + Buy and Resell HDU - 6438

http://codeforces.com/problemset/problem/865/D

http://acm.hdu.edu.cn/showproblem.php?pid=6438

题意略

每一系列交易其实就是一条链 一次完整交易肯定有买有卖 链头链尾就是买入和卖出的日子 中间元素只是中转作用 就像(-1+2)+(-2+3)这样 2只是达成最优交易的一个过度 我们只关心链头链尾 具体体现就是 堆中只维护链尾 链头永远剔除出堆不会再用(因为不能空手套白狼)

在堆中 val为价值 flag标志是否为链头 在cf 865d种只需贪心的考虑 肯定要使赚取的差价尽可能大 所以在所有交易链中挑一个链尾val值最小的 然后看是不是链头 是链头就彻底去掉了

但是在hdu 6438中 还需额外考虑使交易次数最少 其实就是使利益最大化的前提下交易链的条数最少 在堆中当两元素价值一样时 让非链头元素在上即可

cf 865d

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=3e5+10;

struct node
{
    ll val;
    int flag;
    bool friend operator < (node n1,node n2){
        return n1.val>n2.val;
    }
};

priority_queue <node> que;
ll ary[maxn];
int n;

int main()
{
    node cur,tmp;
    ll ans;
    int t,i;
    scanf("%d",&n);
    for(i=1;i<=n;i++){
        scanf("%lld",&ary[i]);
    }
    while(!que.empty()) que.pop();
    tmp.val=ary[1],tmp.flag=0;
    que.push(tmp);
    ans=0;
    for(i=2;i<=n;i++){
        cur=que.top();
        tmp.val=ary[i],tmp.flag=0;
        if(ary[i]>cur.val){
            que.pop();
            ans+=ary[i]-cur.val;
            if(cur.flag){
                cur.flag=0;
                que.push(cur);
            }
            tmp.flag=1;
        }
        que.push(tmp);
    }
    printf("%lld\n",ans);
    return 0;
}

hdu 6438

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+10;

struct node
{
    ll val;
    int flag;
    bool friend operator < (node n1,node n2){
        if(n1.val==n2.val) return n1.flag<n2.flag;
        else return n1.val>n2.val;
    }
};

priority_queue <node> que;
ll ary[maxn];
int n;

int main()
{
    node cur,tmp;
    ll ans1;
    int t,ans2,i;
    scanf("%d",&t);
    while(t--){
        scanf("%d",&n);
        for(i=1;i<=n;i++){
            scanf("%lld",&ary[i]);
        }
        while(!que.empty()) que.pop();
        tmp.val=ary[1],tmp.flag=0;
        que.push(tmp);
        ans1=0,ans2=0;
        for(i=2;i<=n;i++){
            cur=que.top();
            tmp.val=ary[i],tmp.flag=0;
            if(ary[i]>cur.val){
                que.pop();
                ans1+=ary[i]-cur.val;
                if(cur.flag){
                    cur.flag=0;
                    que.push(cur);
                }
                else ans2++;
                tmp.flag=1;
            }
            que.push(tmp);
        }
        printf("%lld %d\n",ans1,2*ans2);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/sunyutian1998/article/details/89392925
今日推荐