【NOIP合并果子】uva 10954 add all【贪心】——yhx

Yup!! The problem name re
ects 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, lets add some
avor 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 1 + 3 = 4, cost = 4 2 + 3 = 5, cost = 5
3 + 3 = 6, cost = 6 2 + 4 = 6, cost = 6 1 + 5 = 6, cost = 6
Total = 9 Total = 10 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.

 1 #include<cstdio>
 2 #include<algorithm>
 3 using namespace std;
 4 int q1[5010],q2[5010],h1,h2,t,n;
 5 int get()
 6 {
 7     if (h1>n)
 8       return q2[h2++];
 9     if (h2>t)
10       return q1[h1++];
11     if (q1[h1]<=q2[h2])
12       return q1[h1++];
13     return q2[h2++];
14 }
15 int main()
16 {
17     int i,j,k,m,p,q,x,y,z,ans;
18     while (scanf("%d",&n)==1&&n)
19     {
20         for (i=1;i<=n;i++)
21           scanf("%d",&q1[i]);
22         sort(q1+1,q1+n+1);
23         ans=0;
24         h1=h2=1;
25         t=0;
26         for (i=1;i<n;i++)
27         {
28             x=get();
29             y=get();
30             ans+=(x+y);
31             q2[++t]=x+y;
32         }
33         printf("%d\n",ans);
34     }
35 }

和某年NOIP合并果子一模一样。

思路是贪心,每次取两个最小值相加。

具体实现方法有两种,一种是优先队列,O(nlogn)。

另一种即是本代码。

由于后得到的元素一定比先得到(是得到的,不算原来的)的元素大,所以可以开两个队列。

一个队列放排好序的没动过的元素,另一个放新得到的元素。由于两个队列都是单调递增的,所以取最小元素只要看两个队列头即可。

正当我以为得出了O(n)算法时,突然发现:排序要O(nlogn)。

于是复杂度还是O(nlogn)。

时间: 2024-12-26 04:19:05

【NOIP合并果子】uva 10954 add all【贪心】——yhx的相关文章

UVa 10954 Add All 贪心

贪心   每一次取最小的两个数,注意相加的数也要算' #include<cstring> #include<iostream> #include<cstdio> #include<algorithm> #include<string> #include<queue> using namespace std; int main() { long long a[5005],i; long long b[5005],n; priority_

UVA - 10954 - Add All (贪心)

UVA - 10954 Add All Time Limit: 3000MS Memory Limit: Unknown 64bit IO Format: %lld & %llu Submit Status Description Problem F Add All Input: standard input Output: standard output Yup!! The problem name reflects your task; just add a set of numbers.

uva 10954 Add All(排序)

uva 10954 Add All 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

uva 10954 Add All(哈弗曼编码)

这道题我一开始想错了,这么简单的题都wa了两发...我往贪心上面想了,每次都找一个最小的数相加,结果就是 排序后直接往后加,还在那纳闷为何出错...其实这道题是哈弗曼编码问题,简直是模板题目,就是每次找两个最 小的结点求和后把他们的和放到节点中去,把这两个点删除...用的multiset,其实和set容器差不多,就是可 以存放重复的元素... 代码: #include<iostream> #include<cstdio> #include<cstdlib> #inclu

UVA 10954 Add All 全部相加 (Huffman编码)

题意:给你n个数的集合,每次选两个删除,把它们的和放回集合,直到集合的数只剩下一个,每次操作的开销是那两个数的和,求最小开销. 赤果果的Huffman码了.用两个队列类似归并排序,合并一下. #include<bits/stdc++.h> using namespace std; const int maxn = 5010; int q1[maxn]; int q2[maxn]; #define GetMin(x)if(head1>=rear1 || (head2<rear2 &a

UVA - 10954 Add All (全部相加)(Huffman编码 + 优先队列)

题意:有n(n <= 5000)个数的集合S,每次可以从S中删除两个数,然后把它们的和放回集合,直到剩下一个数.每次操作的开销等于删除的两个数之和,求最小总开销.所有数均小于10^5. 分析:按此操作,最终变成1个数,需要n-1次操作,要想总开销最小,就使每次取出的两数之和最小,优先队列. #pragma comment(linker, "/STACK:102400000, 102400000") #include<cstdio> #include<cstrin

noip 合并果子

#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<string> #include<algorithm> #include<queue> #include<vector> #include<set> using namespace std; pr

NOIP提高组2004 合并果子题解

NOIP提高组2004 合并果子题解 描述:在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆.多多决定把所有的果子合成一堆. 每一次合并,多多可以把两堆果子合并到一起,消耗的体力等于两堆果子的重量之和.可以看出,所有的果子经过n-1次合并之后,就只剩下一堆了.多多在合并果子时总共消耗的体力等于每次合并所耗体力之和. 因为还要花大力气把这些果子搬回家,所以多多在合并果子时要尽可能地节省体力.假定每个果子重量都为1,并且已知果子的种类数和每种果子的数目,你的任务是设计出

【贪心】vijos 1097 合并果子

描述 在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆.多多决定把所有的果子合成一堆. 每一次合并,多多可以把两堆果子合并到一起,消耗的体力等于两堆果子的重量之和.可以看出,所有的果子经过n-1次合并之后,就只剩下一堆了.多多在合并果子时总共消耗的体力等于每次合并所耗体力之和. 因为还要花大力气把这些果子搬回家,所以多多在合并果子时要尽可能地节省体力.假定每个果子重量都为1,并且已知果子的种类数和每种果子的数目,你的任务是设计出合并的次序方案,使多多耗费的体力最少,