最優合併問題

最優合併問題

     給定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));
}




發佈了161 篇原創文章 · 獲贊 70 · 訪問量 19萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章