zoukankan      html  css  js  c++  java
  • POJ3253Fence Repair(优先队列或单调队列)

    http://poj.org/problem?id=3253

    经典题目了,大意是说如果要切断一个长度为a的木条需要花费代价a, 问要切出要求的n个木条所需的最小代价。

    无论是以下哪种方法,最原始的思路就是从相反的角度思考,将每两个合并,花费的代价是他们两个的和,一直到最后只剩下一个

    方法一:

    使用STL的priority_queue,先将所有的木条放入到队列中。每次取出两个木条将他们的长度相加,加入到花费当中去,然后放回到队列中。

    这样计算的时间复杂度就是O(NlogN)。

    方法二:

    使用单调队列,我们可以分析到,由于每次取出的都是优先队列中最小的两个,也就是首部的两个,那我们可以考虑另外借用一个数组b用来存放每次取出的两个数的和,我们注意到,每次取出来的两个数相加,得到的和也是单调递增的(这个很容易证明),可以看下面的例子:

    原始状态:

    a    1 3 5 6 7 8 9

    b    null

    第一次在a里取出两个数1,3相加,放入b中:

    a    5 6 7 8 9

    b    4

    这里我们先从a、b两个数组队首取出一个最小的数4,再从两个数组的队首取出一个最小的数(此时b数组已经队空)5,相加后放入b:

    a    6 7 8 9

    b    9

    同理,这次会取出6和7,相加放入b(注意每次相加的结果都是放入b中的,这里不放入a中是为了保证a和b数组的单调性):

    a    8 9

    b    9 13

    经过几次操作后会得到:

    a    null

    b    39

    最后a队列空,b队列只剩下一个数,这时合并就结束了

    我们可以注意到,由于每次都将相加得到的和放进了b队列,所以b一定是单调递增的, 而且最后平均每个数只被使用了一次,所以它的复杂度是O(N)的。

    单调队列   和   优先队列:

     1 #include <map>
     2 #include <set>
     3 #include <stack>
     4 #include <queue>
     5 #include <cmath>
     6 #include <ctime>
     7 #include <vector>
     8 #include <cstdio>
     9 #include <cctype>
    10 #include <cstring>
    11 #include <cstdlib>
    12 #include <iostream>
    13 #include <algorithm>
    14 using namespace std;
    15 #define INF 0x3f3f3f3f
    16 #define mem0(a) memset(a,0,sizeof(a))
    17 #define mem1(a) memset(a,-1,sizeof(a))
    18 #define lson k<<1, L, mid
    19 #define rson k<<1|1, mid+1, R
    20 
    21 typedef long long LL;
    22 const double eps = 1e-12;
    23 const int MAXN = 100005;
    24 const int MAXM = 500005;
    25 
    26 int main()
    27 {
    28     int N, len;
    29     while(~scanf("%d", &N))
    30     {
    31         priority_queue<LL, vector<LL>, greater<LL> >q;
    32         for(int i=0;i<N;i++)
    33         {
    34             scanf("%d", &len);
    35             q.push((LL)len);
    36         }
    37         LL ans = 0;
    38         while(q.size() > 1)
    39         {
    40             LL p = q.top(); q.pop();
    41             p += q.top();    q.pop();
    42             ans += p;
    43             q.push(p);
    44         }
    45         printf("%lld
    ", ans);
    46     }
    47     return 0;
    48 }
     1 #include <map>
     2 #include <set>
     3 #include <stack>
     4 #include <queue>
     5 #include <cmath>
     6 #include <ctime>
     7 #include <vector>
     8 #include <cstdio>
     9 #include <cctype>
    10 #include <cstring>
    11 #include <cstdlib>
    12 #include <iostream>
    13 #include <algorithm>
    14 using namespace std;
    15 #define INF 0x3f3f3f3f
    16 #define mem0(a) memset(a,0,sizeof(a))
    17 #define mem1(a) memset(a,-1,sizeof(a))
    18 #define lson k<<1, L, mid
    19 #define rson k<<1|1, mid+1, R
    20 
    21 typedef long long LL;
    22 const double eps = 1e-12;
    23 const int MAXN = 20005;
    24 const int MAXM = 500005;
    25 
    26 LL a[MAXN], b[MAXN];
    27 
    28 int main()
    29 {
    30     int N;
    31     while(~scanf("%d", &N))
    32     {
    33         mem0(b);
    34         for(int i=0;i<N;i++) scanf("%lld", &a[i]);
    35         sort(a, a+N);
    36         int frontA=0, frontB=0, rearB=0, num=0;
    37         LL ans=0;
    38         while(++num<N)
    39         {
    40             int sum = 0;
    41             if(frontB==rearB || (frontA<N&&a[frontA]<b[frontB])) { sum += a[frontA]; frontA ++; }
    42             else { sum += b[frontB]; frontB++; }
    43             if(frontB==rearB || (frontA<N&&a[frontA]<b[frontB])) { sum += a[frontA]; frontA ++; }
    44             else { sum += b[frontB]; frontB++; }
    45             b[rearB++] = sum;
    46             ans += sum;
    47         }
    48         printf("%lld
    ", ans);
    49     }
    50     return 0;
    51 }
  • 相关阅读:
    面向对象程序设计简介(1/2)
    iOS官方Sample大全
    AFN不支持 "text/html" 的数据的问题:unacceptable content-type: text/html
    谈ObjC对象的两段构造模式
    关于self和super在oc中的疑惑与分析 (self= [super init])
    在Xcode中使用Git进行源码版本控制
    NSObject之二
    NSObject之一
    Objective-C Runtime 运行时之六:拾遗
    Objective-C Runtime 运行时之五:协议与分类
  • 原文地址:https://www.cnblogs.com/gj-Acit/p/3575719.html
Copyright © 2011-2022 走看看