https://loj.ac/problem/10005 题目描述 有n个数,每次操作选择两个数,删去,并往数列中加入a×b+1,求出剩下一个数时其最大值和最小值的差 思路 显然,我们只需分别求出最大值和最小值即
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; }