题目描述:
给定k个排好序的序列s1,s2,…,sk,
用2路合并算法将这k个序列合并成一个序列。
假设所采用的2路合并算法合并2个长度为m和n的序列需要m+n-1次比较。
设计一个算法确定2路合并次序,使所需的总比较次数最少。
贪心算法分析:
要想使总比较次数最少,需要先合并短的序列,
使短序列合并最多次,使长序列合并最少次。
即每次选长度最短的序列进行合并
新学知识:
vextor<>容器的使用和其中的方法的
#include<iostream>
#include<bits/stdc++.h>
#include<vector>
using namespace std;
vector<int> v;
/*
举例:有四个分别排好的序列,每一个序列含有的数字个数为{5,12,11,2}
将它们合并成一个有序序列 ,
最少需要多少次比较
对于给定序列
哈夫曼树如下
30
12 18
11 7
5 2
最少应该是52次比较(2+5-1)+(11+7-1)+(18+12-1)=6+17+29= 52
程序应该结果是52次
*/
int MinCompTime(){
vector<int> v2(v);
int sum_comp_time;
sort(v2.begin(),v2.end());
while(v2.size()>1){
int t=0;
t+=v2[0];//这一句和下一句,将现存数字集合的最小的两个取出来
t+=v2[1];
v2.push_back(t);//此时的t为最小两数之和,将这个新数插入现存数字集合
t--;//比较次数是两数字之和-1,
sum_comp_time+=t;//更新总比较次数
v2.erase(v2.begin());//erease是移除指定位置元素
v2.erase(v2.begin());
sort(v2.begin(),v2.end());//重新将现存数字集合排序
}
return sum_comp_time;
}
int main(){
int n,num;
cout<<"请问你要输入几个序列"<<endl;
cin>>n;
cout<<"请给出你的数字"<<endl;
for(int i=0;i<n;i++){
cin>>num;
v.push_back(num);
}
cout<<MinCompTime();
}
结果展示如下