题目
原题链接:http://codeforces.com/problemset/problem/884/D
现有一堆小石子,要求按要求的数目分成N堆,分别为a1、a2、...an。具体的,每次选一个堆(其重量为代价),分成2或3堆。求最小的可能代价。
思路
我们反向考虑,就是一个不断合并的过程。当n为奇数,我们总能找到三个最小的合并,直到只剩一堆;当n为偶数,先选择最小的两个合并,再按奇数一样处理。(为了统一起来,添加一个辅助堆,石子个数为0)
代码实现
1 #include<stdio.h> 2 #include<iostream> 3 #include<queue> 4 using namespace std; 5 6 typedef long long ll; 7 int n; 8 9 int main() 10 { 11 while (scanf("%d",&n) == 1) 12 { 13 priority_queue<ll,vector<ll>,greater<ll> >q; 14 ll ans = 0; 15 for (int i = 0; i < n; i++) 16 { 17 int tmp; 18 scanf("%d", &tmp); 19 q.push(tmp); 20 } 21 if ((n & 1) == 0) q.push(0); //n为偶数,补充一个0 22 while (q.size() > 1) 23 { 24 ll a = q.top(); q.pop(); 25 ll b = q.top(); q.pop(); 26 ll c = q.top(); q.pop(); 27 ans += (a + b + c); 28 q.push(a + b + c); 29 } 30 q.pop(); 31 printf("%I64d ", ans); 32 } 33 }
参考链接: