输入格式:
第一行有 1 个正整数k,表示有 k个待合并序列。 第二行有 k个正整数,表示 k个待合并序列的长度。
输出格式:
输出最多比较次数和最少比较次数。
输入样例:
在这里给出一组输入。例如:
4
5 12 11 2
输出样例:
在这里给出相应的输出。例如:
78 52
一、贪心策略:
最少对应从待合并序列中每次找最小和次小,最多对应从待合并序列中每次找最大和次大,但是要注意每次得到的和需要与剩下待合并序列进行重新排序!!!
二、代码实现
#include<iostream>
#include<algorithm>
using namespace std;
int main(){
int n;
cin>>n;
int a[n],b[n];
for(int i=0;i<n;i++){
cin>>a[i];
b[i]=a[i];
}
sort(a,a+n);
int minSum=0; // 最小和次数
for(int i=0;i<n-1;i++){ // 对于n个数,两两合并成一个总共需要(n-1)次
minSum+=a[i]+a[i+1]-1; // 取最小和次小
a[i]=a[i]+a[i+1]; // 更新当前i位置的a值
a[i+1]=0; // 更新当前位置的下一个的a值为0
/*
如 : 4 21 22 23
更新一次后为 : 25 0 22 23
*/
sort(a,a+n); // 重新排序
// 如: 0 22 23 25。之后不断这样,直到 i指向(n-2)的位置
}
sort(b,b+n);
int maxSum=0; // 最大和次数
for(int i=0;i<n-1;i++){ // 对于n个数,两两合并成一个总共需要(n-1)次
maxSum+=b[n-1]+b[n-2]-1; // 取最大和次大,(所有的操作都是在最后两个位置上)
b[n-1]=b[n-1]+b[n-2]; // 更新最后位置的b值
b[n-2]=0; // 更新倒数第二位置的b值为 0
/*
如 : 4 21 22 23
更新一次后为 : 4 21 0 45
*/
sort(b,b+n); // 重新排序
// 如: 0 4 21 45。之后不断这样操纵
}
cout<<maxSum<<" "<<minSum<<endl;
return 0;
}