ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2022-08-26 22:30:09  阅读:158  来源: 互联网

标签:begin 14 int 合并 v1 v2 序列 最优 贪心


题目描述:
给定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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有