Problem F
Add All
Input: standard input
Output: standard output
Yup!! The problem name reflects your task; just add a set of numbers. But you may feel yourselves condescended, to write a C/C++ program just to add a set of numbers. Such a problem will simply question your erudition. So, let’s add some flavor of ingenuity to it.
Addition operation requires cost now, and the cost is the summation of those two to be added. So, to add 1 and 10, you need a cost of 11.If you want to add 1, 2 and 3. There are several ways –
|
1 + 2 = 3, cost = 3 3 + 3 = 6, cost = 6 Total = 9 |
1 + 3 = 4, cost = 4 2 + 4 = 6, cost = 6 Total = 10 |
2 + 3 = 5, cost = 5 1 + 5 = 6, cost = 6 Total = 11 |
I hope you have understood already your mission, to add a set of integers so that the cost is minimal.
Input
Each test case will start with a positive number, N (2 ≤ N ≤ 5000) followed by N positive integers (all are less than 100000). Input is terminated by a case where the value of N is zero. This case should not be processed.
Output
For each case print the minimum total cost of addition in a single line.
Sample Input Output for Sample Input
|
3 1 2 3 4 1 2 3 4 0 |
9 19
|
Problem setter: Md. Kamruzzaman, EPS
#include <cstdio>
#include <algorithm>
#include <queue>
using namespace std;
long long array[5010];
queue<long long> my_queue;
int main()
{
int n;
while(scanf("%d", &n) && n != 0)
{
my_queue = queue<long long>();
for(int i = 0; i < n; i++)
scanf("%lld", &array[i]);
sort(array, array+n);
long long sum = 0;
/* long long pre_sum = 0;
for(int i = 1; i <= n-1; i++)
{
if(i == 1)
{
sum = array[i] + array[i-1];
pre_sum = array[i] + array[i-1];
}
else
{
pre_sum = pre_sum + array[i];
sum = sum + pre_sum;
}
}
printf("%lld\n", sum);
*/
// 将开头的两个数字相加,其和放入队列中
long long num = array[0] + array[1];
sum = sum + num;
my_queue.push(num);
int place = 2;
// int r_count = n-1;
while(1)
{
// printf("here\n");
// 如果仅剩一个元素,结束
if(place >= n && my_queue.size() == 1)
break;
long long a_num = -1;
long long q_num = -1;
long long num1 = -1;
if(place < n)
a_num = array[place];
if(my_queue.size() >= 1)
q_num = my_queue.front();
if(a_num == -1)
{
num1 = q_num;
my_queue.pop();
}
else if(q_num == -1)
{
num1 = a_num;
place++;
}
else if(a_num < q_num)
{
num1 = a_num;
place++;
}
else if(a_num >= q_num)
{
num1 = q_num;
my_queue.pop();
}
a_num = -1;
q_num = -1;
long long num2 = -1;
if(place < n)
a_num = array[place];
if(my_queue.size() >= 1)
q_num = my_queue.front();
if(a_num == -1)
{
num2 = q_num;
my_queue.pop();
}
else if(q_num == -1)
{
num2 = a_num;
place++;
}
else if(a_num < q_num)
{
num2 = a_num;
place++;
}
else if(a_num >= q_num)
{
num2 = q_num;
my_queue.pop();
}
num = num1 + num2;
sum = sum + num;
my_queue.push(num);
}
printf("%lld\n", sum);
}
return 0;
}
一开始想排序然后从小到大依次相加相邻的两个数,就是答案,后来发现错了。
仔细想一下是,每次取最小的两个数相加。和Huffman编码解法一样。
可以不用优先队列,用另外一个队列来存算出来的两个数的和,由于每次算出来的两个数的和肯定比以前算出来的和要大,所以直接加入队尾即可。
692

被折叠的 条评论
为什么被折叠?



