其他分享
首页 > 其他分享> > 14.最优合并问题(贪心)

14.最优合并问题(贪心)

作者:互联网

题目描述:
给定k 个排好序的序列s1 , s2,……, sk , 用2 路合并算法将这k 个序列合并成一个序列。假设所采用的2 路合并算法合并2 个长度分别为m和n的序列需要m + n -1次比较。试设计一个算法确定合并这个序列的最优合并顺序,使所需的总比较次数最少。
为了进行比较,还需要确定合并这个序列的最差合并顺序,使所需的总比较次数最多。
对于给定的k个待合并序列,计算最多比较次数和最少比较次数合并方案。

输入:
输入数据的第一行有1 个正整数k(k≤1000),表示有k个待合并序列。接下来的1 行中,有k个正整数,表示k个待合并序列的长度。

输出:
输出两个整数,中间用空格隔开,表示计算出的最多比较次数和最少比较次数。

样例①
输入

4
5 12 11 2

输出

78 52

代码:

#include<bits/stdtr1c++.h>
using namespace std;
//获得最多比较次数
int getMax(vector<int> v1) {
	int sum1 = 0;  //sum记录次数
	sort(v1.begin(), v1.end(), greater<int>()); //按照从大到小排序
	//合并的时候,当size=1时,说明只剩下1个数了,合并完毕
	while (v1.size() > 1) {
		int t = 0; //t为临时变量,用来记录 两个序列合并之后的长度
		t += (v1[0] + v1[1]);
		v1[1] = t;  //让第二个先变成合并之后的长度,两个最大的相加之后赋给第二个值,可以保证还是有序的
		sum1 += (t - 1);
		v1.erase(v1.begin()); //把开头第一个数删掉
	}
	return sum1;
}
//获得最小比较次数,稍微麻烦些,需要每合并两个就要进行排序一次,因为合并完的需要重新放到vector中,但是无论是放到开头还是放到末尾,都不能保证有序,所以需要重新排序。
int getMin(vector<int> v2) {
	int sum2 = 0;
	sort(v2.begin(), v2.end());
	while (v2.size() > 1) {
		int t = 0;
		t += (v2[0] + v2[1]);
		v2.emplace_back(t);
		sum2 += (t - 1);
		v2.erase(v2.begin(), v2.begin() + 2);
		sort(v2.begin(), v2.end());
	}
	return sum2;
}
int main() {
	int n;
	vector<int> v;
	cin >> n;
	int num;
	for (int i = 0; i < n; i++) {
		cin >> num;
		v.emplace_back(num);
	}
	cout << getMax(v) << " " << getMin(v);
	return 0;
}

标签:begin,14,int,合并,v1,v2,序列,最优,贪心
来源: https://www.cnblogs.com/Fare-well/p/16629450.html