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
相關文章
相關標籤/搜索