1. 程式人生 > >【單調隊列】合並果子

【單調隊列】合並果子

mem open 打了 amp mod 並且 包含 證明 int

題目描述

在一個果園裏,多多已經將所有的果子打了下來,而且按果子的不同種類分成了不同的堆。多多決定把所有的果子合成一堆。
每一次合並,多多可以把兩堆果子合並到一起,消耗的體力等於兩堆果子的重量之和。可以看出,所有的果子經過n-1次合並之後,就只剩下一堆了。多多在合並果子時總共消耗的體力等於每次合並所耗體力之和。
因為還要花大力氣把這些果子搬回家,所以多多在合並果子時要盡可能地節省體力。假定每個果子重量都為1,並且已知果子的種類數和每種果子的數目,你的任務是設計出合並的次序方案,使多多耗費的體力最少,並輸出這個最小的體力耗費值。
例如有3種果子,數目依次為1,2,9。可以先將1、2堆合並,新堆數目為3,耗費體力為3。接著,將新堆與原先的第三堆合並,又得到新的堆,數目為12,耗費體力為12。所以多多總共耗費體力=3+12=15。可以證明15為最小的體力耗費值。

輸入

輸入包括兩行,第一行是一個整數n(1<=n<=10000),表示果子的種類數。第二行包含n個整數,用空格分隔,第i個整數ai(1<=ai<=20000)是第i種果子的數目。

輸出

輸出包括一行,這一行只包含一個整數,也就是最小的體力耗費值。輸入數據保證這個值小於2^31。

樣例輸入

3 
1 2 9

樣例輸出

15 

題解

就是先排一下序,然後兩個相加,加出來的數放到另一個數組裏,然後每
技術分享圖片
#include <bits/stdc++.h>
#define ll long long
#define met(a) memset(a,0,sizeof(a))
#define
inf 0x3f3f3f3f using namespace std; const int mod=1e9+7; int a[10010]; int main() { int i,j,k,m,n; cin>>n; for (i = 1; i <=n; i++) cin >> a[i]; sort(a+1,a+n+1); int st = 1, ed = n+1, st1 = 0, ed1 = 0; ll ans=0,cnt; while (1) { cnt=0; if
(st == ed&&st1 + 1 == ed1) break; for (j =1; j <=2; j++) { if (st != ed) { if (st1 != ed1) if(a[st]<a[st1]) { cnt+=a[st]; st++; } else { cnt+=a[st1]; st1++; } else { cnt+= a[st]; st++; } } else { cnt += a[st1]; st1++; } } ans += cnt; a[ed1++] = cnt; } cout << ans<< endl; return 0; }
View Code

到一個就比較二者的大小。

【單調隊列】合並果子