• 牛客练习赛38 E 出题人的数组 2018ccpc桂林A题 贪心


    https://ac.nowcoder.com/acm/contest/358/E

    题意:


    出题人有两个数组,A,B,请你把两个数组归并起来使得cost=ici 最小,归并要求原数组的数的顺序在新数组中不改变。

    题解:

    先分别处理A和B数组,把A先分成n段,把某段均值大于前面的一段,就把这两段合并。处理完A,B段后就可以取大原则归并。

    #include <algorithm>
    #include  <iterator>
    #include  <iostream>
    #include   <cstring>
    #include   <cstdlib>
    #include   <iomanip>
    #include    <bitset>
    #include    <cctype>
    #include    <cstdio>
    #include    <string>
    #include    <vector>
    #include     <stack>
    #include     <cmath>
    #include     <queue>
    #include      <list>
    #include       <map>
    #include       <set>
    #include   <cassert>
    
    using namespace std;
    #define lson (l , mid , rt << 1)
    #define rson (mid + 1 , r , rt << 1 | 1)
    #define debug(x) cerr << #x << " = " << x << "
    ";
    #define pb push_back
    #define pq priority_queue
    
    
    
    typedef long long ll;
    typedef unsigned long long ull;
    //typedef __int128 bll;
    typedef pair<ll ,ll > pll;
    typedef pair<int ,int > pii;
    typedef pair<int,pii> p3;
    
    //priority_queue<int> q;//这是一个大根堆q
    //priority_queue<int,vector<int>,greater<int> >q;//这是一个小根堆q
    #define fi first
    #define se second
    //#define endl '
    '
    
    #define OKC ios::sync_with_stdio(false);cin.tie(0)
    #define FT(A,B,C) for(int A=B;A <= C;++A)  //用来压行
    #define REP(i , j , k)  for(int i = j ; i <  k ; ++i)
    #define max3(a,b,c) max(max(a,b), c);
    #define min3(a,b,c) min(min(a,b), c);
    //priority_queue<int ,vector<int>, greater<int> >que;
    
    const ll mos = 0x7FFFFFFF;  //2147483647
    const ll nmos = 0x80000000;  //-2147483648
    const int inf = 0x3f3f3f3f;
    const ll inff = 0x3f3f3f3f3f3f3f3f; //18
    const int mod = 1e8+7;
    const double esp = 1e-8;
    const double PI=acos(-1.0);
    const double PHI=0.61803399;    //黄金分割点
    const double tPHI=0.38196601;
    
    
    template<typename T>
    inline T read(T&x){
        x=0;int f=0;char ch=getchar();
        while (ch<'0'||ch>'9') f|=(ch=='-'),ch=getchar();
        while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
        return x=f?-x:x;
    }
    
    
    /*-----------------------showtime----------------------*/
    
                const int maxn = 1e5+9;
                int A[maxn],B[maxn];
    
                struct node{
                    ll sum;int cnt;
    
                    friend bool operator < (node a, node b){
                        return a.sum * b.cnt < b.sum * a.cnt;
                    }
                    friend node operator + (node a,node b){
                        return (node) {a.sum + b.sum, a.cnt + b.cnt};
                    }
                }S[maxn],T[maxn];
                int C[maxn*2];
    
    
                void add(int op, int l,int r,int &now){
                        for(int i=l; i<=r; i++){
                            if(op==1) C[now++] = A[i];
                            else C[now++] = B[i];
                        }
                }
    int main(){
                int n,m;    scanf("%d%d", &n, &m);
    
                for(int i=1; i<=n; i++) {
                    scanf("%d", &A[i]);
                }
                for(int i=1; i<=m; i++){
                    scanf("%d", &B[i]);
                }
                int tot1 = 0;
                for(int i=1; i<=n; i++){
                    S[++tot1] = (node) {A[i], 1};
                    while(tot1>1 && S[tot1-1] < S[tot1]){
                        S[tot1-1] = S[tot1-1] + S[tot1];
                        tot1--;
                    }
                }
    
                int tot2 = 0;
    
                for(int i=1; i<=m; i++){
                    T[++tot2] = (node) {B[i], 1};
                    while(tot2 > 1&& T[tot2-1] < T[tot2]){
                        T[tot2-1] = T[tot2-1] + T[tot2];
                        tot2--;
                    }
                }
    
                S[++tot1] = (node){-1, 1};
                T[++tot2] = (node){-1, 1};
    
                int L=1,R=1;
                int prel=1,prer=1,now=1;
                while(L < tot1 || R < tot2){
                    if(S[L] < T[R]){
                        add(2, prer,prer+T[R].cnt-1,now);
                        prer += T[R].cnt;
                        R++;
                    }
                    else {
                        add(1, prel,prel+S[L].cnt-1,now);
                        prel += S[L].cnt;
                        L++;
                    }
                }
                ll ans = 0;
                for(int i=1; i<=n+m;i++){
                    ans += 1ll*i*C[i];
                   // cout<<C[i]<<" ";
                }
               // cout<<endl;
                printf("%lld
    ", ans);
                return 0;
    }
  • 相关阅读:
    算法:拓扑排序
    【欧拉计划2】Even Fibonacci numbers
    机房收费系统之模版方法使用
    VC运行时库
    数据库学习(6)——基本查询操作
    Attribute与Property的区别
    记C++类成员访问权限符二三事
    大年初五去颐和园
    2013年第6周六农历除夕下午
    大年初四晚上睡前
  • 原文地址:https://www.cnblogs.com/ckxkexing/p/10294097.html
Copyright © 2020-2023  润新知