1. 程式人生 > >NYOJ 55 懶省事的小明(哈弗曼樹)

NYOJ 55 懶省事的小明(哈弗曼樹)

pad sans div sam time span border dsm 方案

懶省事的小明

時間限制:3000 ms | 內存限制:65535 KB 難度:3
描寫敘述
小明非常想吃果子,正好果園果子熟了。

在果園裏,小明已經將全部的果子打了下來,並且按果子的不同種類分成了不同的堆。小明決定把全部的果子合成一堆。

由於小明比較懶。為了省力氣,小明開始想點子了:
  每一次合並,小明能夠把兩堆果子合並到一起,消耗的體力等於兩堆果子的重量之和。

能夠看出,全部的果子經過n-1次合並之後。就僅僅剩下一堆了。

小明在合並果子時總共消耗的體力等於每次合並所耗體力之和。
  由於還要花大力氣把這些果子搬回家,所以小明在合並果子時要盡可能地節省體力。假定每一個果子重量都為1,而且已知果子的種類數和每種果子的數目,你的任務是設計出合並的次序方案,使小明耗費的體力最少,並輸出這個最小的體力耗費值。


  比如有3種果子,數目依次為1,2。9。

能夠先將1、2堆合並。新堆數目為3。耗費體力為3。

接著。將新堆與原先的第三堆合並。又得到新的堆,數目為12,耗費體力為12。所以小明總共耗費體力=3+12=15。

能夠證明15為最小的體力耗費值。

輸入
第一行輸入整數N(0<N<=10)表示測試數據組數。接下來每組測試數據輸入包括兩行,第一行是一個整數n(1<=n<=12000),表示果子的種類數。

第二行包括n個整數,用空格分隔,第i個整數ai(1<=ai<=20000)是第i種果子的數目。

輸出
每組測試數據輸出包括一行,這一行僅僅包括一個整數,也就是最小的體力耗費值。
例子輸入
1
3 
1 2 9
例子輸出
15




測試了非常多次。沒有AC的原因果然是以下代碼中凝視的部分

#include <iostream>
#include <algorithm>

using namespace std;

int main()
{
	int n,m,i,j;
	long long k,t;
	cin>>n;
	while(n--)
	{
		cin>>m;
		long long *ans=new long long[m];
		for(i=0;i<m;++i)
			cin>>ans[i];

		sort(ans,ans+m);

		k=0;
		for(i=1;i<m;++i)
		{
			k=k+ans[i]+ans[i-1];
			j=i+1;
			ans[i]=ans[i]+ans[i-1];
			while(ans[j-1]>ans[j] && j<m)
			{
/*

				ans[j-1]=ans[j]^ans[j-1];
				ans[j]=ans[j]^ans[j-1];
				ans[j-1]=ans[j]^ans[j-1];

*/
				t=ans[j];
				ans[j]=ans[j-1];
				ans[j-1]=t;

				j++;
			}
		}
		cout<<k<<endl;
	}
	return 0;
}


哎。好好學 計算機組成原理 吧!

NYOJ 55 懶省事的小明(哈弗曼樹)