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 }
  • 相关阅读:
    关联接口,依赖接口的用法
    通过requests发送不同请求格式的数据
    requests请求数据参数化配置
    requests模块中通用的请求方法,即requests.request
    预期方向需要动态调整
    红枣大幅低开高开
    大涨大跌判断风向
    开盘大幅拉升回落
    红枣变盘之前的预测
    开盘情况要稳定才能进,不看看一根线
  • 原文地址:https://www.cnblogs.com/gj-Acit/p/3575719.html
Copyright © 2011-2022 走看看