poj3253

本文地址:http://www.javashuo.com/article/p-mlslnsqi-gc.htmlhtml

题目名称:Fence Repairide

连接:http://poj.org/problem?id=3253spa

题意:农夫准备把木板切成n块,每块长度为Li,每次切木板时须要花费切时木板的长度的开销(好比把21切成13和8,开销就是切以前的长度12)。计算把木板切完的最小开销。3d

思路:直接拿刀去切木板貌似没有什么贪心的思路呀。可是咱们把切的过程画成树的样子就会发现开销等于各叶子节点的 木板长度乘以节点深度 的和。反过来想,最短与次短的两块应该在最下面且是兄弟节点,就是每次把最小的两块合起来,而后依次贪心就能获得最小值。(也就是哈夫曼树)
code

代码以下:htm

一、直接循环查找最小和次小 O(n2)blog

 1 #include<cstdio>
 2 #include<algorithm>
 3 using namespace std;  4 typedef long long ll;  5 int L[20005];  6 int main(){  7     int n;  8     scanf("%d",&n);  9     for(int i = 0; i < n; i++) 10         scanf("%d", &L[i]); 11     ll sum = 0; 12     while(n > 1){ 13         int min1 = 0, min2 = 1; //最小和次小
14         if(L[min1] > L[min2]) 15  swap(min1, min2); 16         for(int i = 2; i < n; i++){ 17             if(L[i] < L[min1]){ 18                 min2 = min1; 19                 min1 = i; 20  } 21             else if(L[i] < L[min2]) 22                 min2 = i; 23  } 24         int t = L[min1] + L[min2]; 25         sum += t; 26         if(min1 == n-1) swap(min1,min2); 27         L[min1] = t; 28         L[min2] = L[n-1]; 29         n--; 30  } 31     printf("%lld\n",sum); 32     return 0; 33 }
View Code

二、用优先队列 O(nlogn)队列

 1 #include<cstdio>
 2 #include<queue>
 3 #include<algorithm>
 4 using namespace std;  5 typedef long long LL;  6 int main() {  7     int n;  8     scanf("%d", &n);  9     priority_queue<int, vector<int>,greater<int> > que; 10     int s; 11     for(int i = 0; i < n; i++) { 12         scanf("%d", &s); 13  que.push(s); 14  } 15     LL ans = 0; 16     while(que.size() > 1) { 17         int s1,s2; 18         s1 = que.top(); 19  que.pop(); 20         s2 = que.top(); 21  que.pop(); 22         ans += s1 + s2; 23         que.push(s1 + s2); 24  } 25     printf("%lld\n", ans); 26     return 0; 27 }
View Code
相关文章
相关标签/搜索