• 数列极差


    https://loj.ac/problem/10005

    题目描述

      有n个数,每次操作选择两个数,删去,并往数列中加入a×b+1,求出剩下一个数时其最大值和最小值的差

    思路

      显然,我们只需分别求出最大值和最小值即可。那么我们只需要思考如何操作会得到最值。我们只考虑最大值,假设数列中有三个数(a,b,c,)并且(a < b < c),那么如果先合并(a,b),再合并(c),代价为((a*b+1)*c+1=a*b*c+c+1);同理,先合并(b,c),再合并(a),代价为((b*c+1)*a+1= a*b*c+a+1);先合并(a,c),再合并(b),代价为(a*b*c+b+1) 。比较可知,先合并(a,b)时结果最大,而(c)可以代表序列中任何比(a、b)大的数,所以先合并(a、b)。最小值也是类似。因此只要经过两次排序,分别处理出最大值和最小值即可。不过我当时用的是优先队列……

    代码

    #include <bits/stdc++.h>
    using namespace std;
    priority_queue<int> q1;
    priority_queue<int,vector<int>,greater<int> >q2;
    int main() 
    {
        int n,x;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&x);
            q1.push(x);q2.push(x);
        }
        scanf("%d",&x);
        for(int i=1;i<n;i++)
        {
            int x=q1.top();q1.pop();
            int y=q1.top();q1.pop();
            q1.push(x*y+1);
        }    
        int minn=q1.top();
        for(int i=1;i<n;i++)
        {
            int x=q2.top();q2.pop();
            int y=q2.top();q2.pop();
            q2.push(x*y+1);
        }    
        int maxx=q2.top();
        printf("%d",maxx-minn);
        return 0;
    }
    
  • 相关阅读:
    每天两题02
    每天两题01
    简单看看原码、补码和反码
    简单看看java之枚举
    随意看看AtomicInteger类和CAS
    js原型链
    简单看看jdk7源码之Object和String
    简单学习js
    element的表单校验自动定位到该位置
    for循环使用element的折叠面板遇到的问题-3
  • 原文地址:https://www.cnblogs.com/fangbozhen/p/11754157.html
Copyright © 2020-2023  润新知