数列极差
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;
}