zoukankan      html  css  js  c++  java
  • 51nod 1117 聪明的木匠 (贪心)

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1117

    跟挑战程序书上例题一样,将要切割的n断木板,分别对应二叉树树的叶子节点,则切割的总开销为木板的长度×节点的深度,可以画图理解,那么最短的木板(L1)应当是深度最大的叶子节点之一,次短的板(L2)和它是兄弟节点,由一块长度是(L1+L2) 的木板切割而来,这样可以变成(n-1)块木板,然后递归求解到n==1。

    书上贪心部分用的是O(n×n) 的算法  在这里会超时,需要2.4节优先队列O(NlogN)的算法。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cmath>
     4 #include <vector>
     5 #include <cstring>
     6 #include <string>
     7 #include <algorithm>
     8 #include <string>
     9 #include <set>
    10 #include <functional>
    11 #include <numeric>
    12 #include <sstream>
    13 #include <stack>
    14 #include <map>
    15 #include <queue>
    16 
    17 #define CL(arr, val)    memset(arr, val, sizeof(arr))
    18 
    19 #define ll long long
    20 #define inf 0x7f7f7f7f
    21 #define lc l,m,rt<<1
    22 #define rc m + 1,r,rt<<1|1
    23 #define pi acos(-1.0)
    24 
    25 #define L(x)    (x) << 1
    26 #define R(x)    (x) << 1 | 1
    27 #define MID(l, r)   (l + r) >> 1
    28 #define Min(x, y)   (x) < (y) ? (x) : (y)
    29 #define Max(x, y)   (x) < (y) ? (y) : (x)
    30 #define E(x)        (1 << (x))
    31 #define iabs(x)     (x) < 0 ? -(x) : (x)
    32 #define OUT(x)  printf("%I64d
    ", x)
    33 #define lowbit(x)   (x)&(-x)
    34 #define Read()  freopen("a.txt", "r", stdin)
    35 #define Write() freopen("b.txt", "w", stdout);
    36 #define maxn 1000000000
    37 #define N 50005
    38 using namespace std;
    39 
    40 int L[N];
    41 int main()
    42 {
    43    // Read();
    44     int n;
    45     long long ans=0;
    46     scanf("%d",&n);
    47     for(int i=0;i<n;i++) scanf("%d",&L[i]);
    48     while(n>1)
    49     {
    50         int m1=0,m2=1;
    51         if(L[m1]>L[m2]) swap(m1,m2);
    52         for(int i=2;i<n;i++)
    53         {
    54             if(L[m1]>L[i])
    55             {
    56                 m2=m1;
    57                 m1=i;
    58             }
    59             else if(L[m2]>L[i])
    60             {
    61                 m2=i;
    62             }
    63         }
    64         //printf("%d %d
    ",L[m1],L[m2]);
    65         int t=L[m1]+L[m2];
    66         ans+=t;
    67         if(m1==n-1) swap(m1,m2);
    68         L[m1]=t;
    69         L[m2]=L[n-1];
    70         n--;
    71     }
    72     printf("%lld
    ",ans);
    73     return 0;
    74 }

    优化后的代码:每次只需要选择长度最小的两块木板,则用优先队列从小到大排序,每次把取出来的两块木板之和压进队列即可。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cmath>
     4 #include <vector>
     5 #include <cstring>
     6 #include <string>
     7 #include <algorithm>
     8 #include <string>
     9 #include <set>
    10 #include <functional>
    11 #include <numeric>
    12 #include <sstream>
    13 #include <stack>
    14 //#include <map>
    15 #include <queue>
    16 
    17 #define CL(arr, val)    memset(arr, val, sizeof(arr))
    18 
    19 #define ll long long
    20 #define inf 0x7f7f7f7f
    21 #define lc l,m,rt<<1
    22 #define rc m + 1,r,rt<<1|1
    23 #define pi acos(-1.0)
    24 
    25 #define L(x)    (x) << 1
    26 #define R(x)    (x) << 1 | 1
    27 #define MID(l, r)   (l + r) >> 1
    28 #define Min(x, y)   (x) < (y) ? (x) : (y)
    29 #define Max(x, y)   (x) < (y) ? (y) : (x)
    30 #define E(x)        (1 << (x))
    31 #define iabs(x)     (x) < 0 ? -(x) : (x)
    32 #define OUT(x)  printf("%I64d
    ", x)
    33 #define lowbit(x)   (x)&(-x)
    34 #define Read()  freopen("a.txt", "r", stdin)
    35 #define Write() freopen("b.txt", "w", stdout);
    36 #define maxn 1000000000
    37 #define N 50005
    38 using namespace std;
    39 
    40 int L[N];
    41 priority_queue<int, vector<int>, greater<int> >que;
    42 int main()
    43 {
    44     //Read();
    45     int n;
    46     scanf("%d",&n);
    47     for(int i=0;i<n;i++)
    48     {
    49         scanf("%d",&L[i]);
    50         que.push(L[i]);
    51     }
    52     ll ans=0;
    53     while(que.size()>1)
    54     {
    55         int l1,l2;
    56         l1=que.top();
    57         que.pop();
    58         l2=que.top();
    59         que.pop();
    60         ans+=l1+l2;
    61         que.push(l1+l2);
    62     }
    63     printf("%lld
    ",ans);
    64     return 0;
    65 }
  • 相关阅读:
    成都磨子桥技工学校 / 数据结构 Challenge 4
    圆桌问题(网络流24题)
    试题库问题(网络流24题)
    [AHOI2005]航线规划
    [AMPPZ2014]The Prices
    方格取数(网络流24题)
    太空飞行计划问题(网络流24题)
    Linux 学习3
    Linux 学习2
    Linux 学习1
  • 原文地址:https://www.cnblogs.com/nowandforever/p/4421844.html
Copyright © 2011-2022 走看看