zoukankan      html  css  js  c++  java
  • 【JZOJ4835】【GDOI2017模拟10.31】量化交易

    题目描述

    这里写图片描述

    数据范围

    这里写图片描述

    解法

    贪心;
    从左往右枚举,设枚举到元素为x,并维护一个堆:
    设此时堆顶元素为y,
    如果x大于y,那么x可以与y产生差价,立即将差价贡献给答案。
    如果y之前已经和其他元素z产生过差价了,那么y显然可以省出来以得到最优答案,因为x-z=x-y+y-z;
    否则,把y移出堆。

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #define ll long long
    #define sqr(x) ((x)*(x))
    #define ln(x,y) ll(log(x)/log(y))
    using namespace std;
    const char* fin="trade.in";
    const char* fout="trade.out";
    const ll inf=0x7fffffff;
    const ll maxn=100008;
    ll n,i,j,k,v=0,ans,t;
    ll a[maxn],son[maxn];
    struct dui{
        ll data[maxn],num;
        void init(){
            memset(data,0,sizeof(data));
            num=0;
        }
        dui(){
            init();
        }
        bool cmp(ll v,ll u){
            return a[v]<=a[u];
        }
        void up(ll x){
            while (x>1 && cmp(data[x],data[x/2])) swap(data[x],data[x/2]),x=x/2;
        }
        void down(ll x){
            while (x*2<=num && cmp(data[x*2],data[x]) || x*2+1<=num && cmp(data[x*2+1],data[x])){
                if (x*2+1>num || cmp(data[x*2],data[x*2+1])){
                    swap(data[x],data[x*2]);
                    x=x*2;
                }else{
                    swap(data[x],data[x*2+1]);
                    x=x*2+1;
                }
            }
        }
        void push(ll v){
            data[++num]=v;
            up(num);
        }
        void pull(){
            swap(data[1],data[num--]);
            down(1);
        }
        ll top(){
            if (num) return data[1];
            else return 0;
        }
    }d;
    ll read(){
        ll x=0,y=0;
        char ch=getchar();
        while (ch<'0' || ch>'9') {
            ch=getchar();
            y++;
            if (y==10) return -1;
        }
        while (ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
        return x;
    }
    int main(){
        freopen(fin,"r",stdin);
        freopen(fout,"w",stdout);
        while (1){
            n=read();
            if (n==-1) break;
            ans=0;
            t++;
            d.init();
            for (i=1;i<=n;i++) a[i]=read();
            memset(son,0,sizeof(son));
            for (i=1;i<=n;i++){
                if (d.top()){
                    j=d.top();
                    if (a[i]>a[j]){
                        ans+=a[i]-a[j];
                        if (son[j]){
                            son[j]=0;
                            son[i]=j;
                        }else {
                            d.pull();
                            son[i]=j;
                        }
                    }
                }
                d.push(i);
            }
            printf("Case #%lld: %lld
    ",t,ans);
        }
        return 0;
    }

    启发

    有关策略的问题可以考虑贪心;
    贪心正着推,可以使用数据结构帮助贪心找到更优的解。

  • 相关阅读:
    jvm-类加载
    jvm调优
    jdk8与jdk9的共存
    eclipse的插件开发-启动时间
    斐波那契数列算法逐层优化(C++)
    2G.处女座与复读机(C++)
    3I.处女座的约会(C++)
    3D.处女座的训练(C++)
    3E.处女座和小姐姐(C++)
    3C.处女座点名(C++)
  • 原文地址:https://www.cnblogs.com/hiweibolu/p/6714859.html
Copyright © 2011-2022 走看看