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

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

时间:2022-08-26 22:33:23浏览次数:55  
标签: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,序列,最优,贪心
From: https://www.cnblogs.com/Fare-well/p/16629450.html

相关文章

  • 10. 汽车加油问题(贪心)
    题目描述:一辆汽车加满油后可行驶n公里。旅途中有若干个加油站。设计一个有效算法,指出应在哪些加油站停靠加油,使沿途加油次数最少。并证明算法能产生一个最优解。对于给......
  • LeetCode 14. 最长公共前缀
    题目题目链接:https://leetcode.cn/problems/longest-common-prefix/编写一个函数来查找字符串数组中的最长公共前缀。如果不存在公共前缀,返回空字符串 ""。示例1:输......
  • react18-学习笔记14-枚举(Enum)
    enumDirection{Up="Up",Down="Down",Left="Left",Right="Right"}console.log(Direction.Up)//0console.log(Direction[0])//Up//常量枚举可以......
  • Python_14文件操作
    一、文件操作:Python提供了必要的函数和方法进行默认情况下的文件基础操作。可以用file对象做大部分的文件操作。open函数,你必须先用Python内置的open函数打开一个文件,创建......
  • leetcode147:对链表进行插入排序
    packagecom.mxnet;publicclassSolution147{publicstaticvoidmain(String[]args){}/***Q:给定单个链表的头head,使用插入排序对链......
  • P1415 题解
    前言题目传送门!更好的阅读体验?这题是一道挺好的\(\texttt{dp}\)题啊,但大家的题解都写得不够详细。所以,我来补一篇\(\LaTeX\)题解,希望能帮助大家。思路首先是读......
  • Codeforces Round #814 (Div. 2) A-D2
    A:ChipGame题意:只能向上走和向右走,走到右上角,最后一步谁操作谁就赢只要判断总步数的奇偶性就可以了//-------------------------代码----------------------------......
  • P4597 & CF713C 【小根堆贪心】
    P4597序列sequenceCF713CSonyaandProblemWihtoutaLegend用于描述一系列问题类似在一条序列上每次加一或减一,使他的原序列变成一条非降序列,求最小次数的问题。......
  • leetcode144:二叉树的前序遍历
    packagecom.mxnet;importjava.util.ArrayList;importjava.util.List;publicclassSolution144{publicstaticvoidmain(String[]args){}/**......
  • Educational Codeforces Round 106 (Rated for Div. 2) | CF1499
    E一个暴力是显然的,\(f(i,j,k)\)表示当前已经使用\(a\)的前\(i\)位,\(b\)的前\(j\)位,最后一位是\(a\)还是\(b\)的。然后\(O(n^2)\)枚举起点跑下去即可。为啥......