最優合併問題
給定k個排好序的序列s1,s2,…,sk,用2路合併算法將這k個序列合併成一個序列。假設所採用的2路合併算法合併兩個長度分別爲m和n的序列需要m+n-1次比較。試設計一個算法確定合併這個序列的最優合併順序,使所需要的總比較次數最少。
測試用例:
4(序列數)
5 1211 2(序列中的元素數)
輸出:
78(最差情況)
52(最優情況)
解:
最優合併問題:
當取最小值保證每次的2個加數爲最小便可,最大值同理取當前最大的兩個值便可
請看下面序列
3,6,5,12,7
如果排好序之後依次按照,找最小連個數進行相加
排好序之後3,5,6,7,12
最小值3+5 = 8 8,6,7,12 按照排序的思路此時不能保證當前數組中前兩位是最小值,所以還要排序
6,7,8,12 6+7 = 13 -->13,8,12
繼續排序
最後按照題意m和n的序列需要m+n-1 次比較
所以在比較中每次減一。
這樣便求出了最小值
#include <stdio.h>
#include <algorithm>
using namespace std;
int n;
int cmp(int a,int b)
{
return a>b;
}
int minsum(int a[],int m)
{
int b[n];
int sum=0;
for(int i=0;i<n;i++)
{
b[i]=a[i];
}
while(m>1)
{
sort(b,b+m);
b[0]=b[0]+b[1];
sum+=b[0];
for(int i=1;i<m-1;i++)
{
b[i]=b[i+1];
}
m--;
}
return sum-n+1;
}
int maxsum(int a[],int m)
{
int b[n];
int sum=0;
for(int i=0;i<n;i++)
{
b[i]=a[i];
}
while(m>1)
{
sort(b,b+m,cmp);
b[0]=b[0]+b[1];
sum+=b[0];
for(int i=1;i<m-1;i++)
{
b[i]=b[i+1];
}
m--;
}
return sum-n+1;
}
int main()
{
int a[100];
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
printf("min:%d\n",minsum(a,n));
printf("max:%d\n",maxsum(a,n));
}