Poj--3253(贪心 / 优先队列)
2014-11-30 19:42:25
思路:思考得最优解肯定是越长的越早分离出来,越短的越后分出来(即:最短的算的次数最多),那么我们可以倒过来考虑,从集合中把最短的两根取出,合并,再加入集合,中间累加...一直到集合中就剩下一个元素停止。可以直接暴力贪心O(n*n),优先队列是O(nlog(n))
(1)贪心(个人感觉这个贪心的姿势挺优美,参考自巫大叔)
1 /************************************************************************* 2 > File Name: 3253.cpp 3 > Author: Nature 4 > Mail: 564374850@qq.com 5 > Created Time: Sun 30 Nov 2014 06:37:40 PM CST 6 ************************************************************************/ 7 8 #include <cstdio> 9 #include <cstring> 10 #include <cstdlib> 11 #include <cmath> 12 #include <vector> 13 #include <map> 14 #include <set> 15 #include <stack> 16 #include <queue> 17 #include <iostream> 18 #include <algorithm> 19 using namespace std; 20 #define lp (p << 1) 21 #define rp (p << 1|1) 22 #define getmid(l,r) (l + (r - l) / 2) 23 #define MP(a,b) make_pair(a,b) 24 typedef long long ll; 25 const int INF = 1 << 30; 26 27 int N,L[20010],min1,min2; 28 ll ans; 29 30 int main(){ 31 while(scanf("%d",&N) != EOF){ 32 min1 = min2 = INF; 33 for(int i = 1; i <= N; ++i){ 34 scanf("%d",L + i); 35 } 36 ans = 0; 37 while(N > 1){ 38 min1 = 1; 39 min2 = 2; 40 if(L[min1] > L[min2]) swap(min1,min2); 41 for(int i = 3; i <= N; ++i){ 42 if(L[i] < L[min1]){ 43 min2 = min1; 44 min1 = i; 45 } 46 else if(L[i] < L[min2]){ 47 min2 = i; 48 } 49 } 50 int t = L[min1] + L[min2]; 51 ans += t; 52 if(min1 == N) swap(min1,min2); 53 L[min1] = t; 54 L[min2] = L[N--]; 55 } 56 printf("%I64d\n",ans); 57 } 58 return 0; 59 }
(2)优先队列
1 /************************************************************************* 2 > File Name: 3253_2.cpp 3 > Author: Nature 4 > Mail: 564374850@qq.com 5 > Created Time: Sun 30 Nov 2014 07:12:55 PM CST 6 ************************************************************************/ 7 8 #include <cstdio> 9 #include <cstring> 10 #include <cstdlib> 11 #include <cmath> 12 #include <vector> 13 #include <map> 14 #include <set> 15 #include <stack> 16 #include <queue> 17 #include <iostream> 18 #include <algorithm> 19 using namespace std; 20 #define lp (p << 1) 21 #define rp (p << 1|1) 22 #define getmid(l,r) (l + (r - l) / 2) 23 #define MP(a,b) make_pair(a,b) 24 typedef long long ll; 25 const int INF = 1 << 30; 26 27 int N,v; 28 ll ans; 29 30 int main(){ 31 while(scanf("%d",&N) != EOF){ 32 priority_queue<int,vector<int>,greater<int> > Q; 33 for(int i = 1; i <= N; ++i){ 34 scanf("%d",&v); 35 Q.push(v); 36 } 37 ans = 0; 38 int min1,min2; 39 while(1){ 40 min1 = Q.top(); Q.pop(); 41 if(Q.empty()){ 42 break; 43 } 44 min2 = Q.top(); Q.pop(); 45 ans += min1 + min2; 46 Q.push(min1 + min2); 47 } 48 printf("%I64d\n",ans); 49 } 50 return 0; 51 }