大意:让你按照某一顺序使得给定的数字的和最小。
思路:贪心性质可以被证明,见刘汝佳白书P156,可以用哈夫曼树来做,我用的是优先队列。
CODE:
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <queue>
using namespace std;
#define MAXN 5010
int n;
int a[MAXN], sum[MAXN];
struct cmp
{
bool operator() (const int a, const int b) //a的优先级比b小时返回true
{
return a > b; //数字大的优先级反而小
}
};
priority_queue<int, vector<int>, cmp> q;
//priority_queue<int, vector<int>, greater<int> > q;
void init()
{
memset(sum, 0, sizeof(sum));
while(!q.empty()) q.pop(); //很有必要
}
int main()
{
while(scanf("%d", &n) && n)
{
init();
int ans = 0, tot = 0;
for(int i = 0; i < n; i++)
{
int a;
scanf("%d", &a);
q.push(a);
}
if(q.size() == 1) ans = q.top();
while(q.size() != 1)
{
int num = 0;
num += q.top(); q.pop();
num += q.top(); q.pop();
sum[tot++] = num;
q.push(num);
}
for(int i = 0; i < n-1; i++) ans += sum[i];
printf("%d\n", ans);
}
return 0;
}
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <queue>
using namespace std;
#define MAXN 5010
int n;
int a[MAXN], sum[MAXN];
struct cmp
{
bool operator() (const int a, const int b) //a的优先级比b小时返回true
{
return a > b; //数字大的优先级反而小
}
};
priority_queue<int, vector<int>, cmp> q;
//priority_queue<int, vector<int>, greater<int> > q;
void init()
{
memset(sum, 0, sizeof(sum));
while(!q.empty()) q.pop(); //很有必要
}
int main()
{
while(scanf("%d", &n) && n)
{
init();
int ans = 0, tot = 0;
for(int i = 0; i < n; i++)
{
int a;
scanf("%d", &a);
q.push(a);
}
if(q.size() == 1) ans = q.top();
while(q.size() != 1)
{
int num = 0;
num += q.top(); q.pop();
num += q.top(); q.pop();
sum[tot++] = num;
q.push(num);
}
for(int i = 0; i < n-1; i++) ans += sum[i];
printf("%d\n", ans);
}
return 0;
}