zoukankan      html  css  js  c++  java
  • 【BZOJ 2288】 2288: 【POJ Challenge】生日礼物 (贪心+优先队列+双向链表)

    2288: 【POJ Challenge】生日礼物

    Description

    ftiasch 18岁生日的时候,lqp18_31给她看了一个神奇的序列 A1A2, ..., AN. 她被允许选择不超过 M 个连续的部分作为自己的生日礼物。

    自然地,ftiasch想要知道选择元素之和的最大值。你能帮助她吗?

    Input

    第1行,两个整数 N (1 ≤ N ≤ 105) 和 M (0 ≤ M ≤ 105), 序列的长度和可以选择的部分。

    第2行, N 个整数 A1A2, ..., AN (0 ≤ |Ai| ≤ 104), 序列。

    Output

    一个整数,最大的和。

    Sample Input


    5 2
    2 -3 2 -1 2

    Sample Output

    5

    HINT

    Source

    【分析】

      我好笨啊。。。

      首先可以把序列弄的好看点,0删掉,负数一段合并,正数一段合并。

      那么就是- + - + - 交替。

      假设我们先把所有正段选了。假设选了cnt段。

      如果cnt<=m,那么这显然就是答案。  

      否则,按照他们的绝对值扔进小根堆里面,每次选队顶元素。ans-=他的值。

      如果选到正数,表示把这个正数删掉,就少了一段。

      如果选到负数,表示把负数两边的两段连起来,也少了一段。

      知道这个意思之后就知道两端的负数是不可以选的,因为没有意义。

      然后删掉那个数之后和两边的两段合并起来重新扔到堆里面做。。【里面包含后悔操作!!!!思考一下!!!!

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cstring>
     4 #include<iostream>
     5 #include<algorithm>
     6 #include<queue>
     7 using namespace std;
     8 #define Maxn 100100
     9 
    10 struct node
    11 {
    12     int id,x;
    13     friend bool operator < (node x,node y)
    14     {
    15         return x.x>y.x;
    16     }
    17 };
    18 
    19 priority_queue<node > q;
    20 
    21 int a[Maxn],w[2*Maxn];
    22 int lt[2*Maxn],nt[2*Maxn];
    23 bool mark[2*Maxn];
    24 
    25 int myabs(int x) {return x<0?-x:x;}
    26 
    27 int main()
    28 {
    29     int n,m;
    30     scanf("%d%d",&n,&m);
    31     for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    32     w[1]=a[1];
    33     int p=1;
    34     for(int i=2;i<=n;i++)
    35     {
    36         if(a[i]==0) continue;
    37         if((a[i]>=0&&w[p]>=0)||(a[i]<=0&&w[p]<=0)) w[p]+=a[i];
    38         else w[++p]=a[i];
    39     }
    40     int cnt=0,ans=0;
    41     for(int i=1;i<=p;i++) if(w[i]>0) cnt++,ans+=w[i];
    42     if(cnt>m)
    43     {
    44         m=cnt-m;
    45         memset(mark,0,sizeof(mark));
    46         while(!q.empty()) q.pop();
    47         for(int i=1;i<=p;i++) nt[i]=i+1;nt[p]=-1;
    48         for(int i=1;i<=p;i++) lt[i]=i-1;
    49         for(int i=1;i<=p;i++)
    50         {
    51             node xx;
    52             xx.id=i;
    53             xx.x=myabs(w[i]);
    54             q.push(xx);
    55         }
    56         cnt=p;
    57         for(int i=1;i<=m;i++)
    58         {
    59             while(mark[q.top().id]) q.pop();
    60             node xx=q.top();q.pop();
    61             if(lt[xx.id]==0)
    62             {
    63                 lt[nt[xx.id]]=0;
    64                 if(w[xx.id]<0)
    65                 {
    66                     i--;
    67                     continue;
    68                 }
    69                 ans-=xx.x;
    70             }
    71             else if(nt[xx.id]==-1)
    72             {
    73                 nt[lt[xx.id]]=-1;
    74                 if(w[xx.id]<0)
    75                 {
    76                     i--;
    77                     continue;
    78                 }
    79                 ans-=xx.x;
    80             }
    81             else
    82             {
    83                 ans-=xx.x;
    84                 mark[lt[xx.id]]=mark[nt[xx.id]]=1;
    85                 cnt++;
    86                 nt[lt[lt[xx.id]]]=lt[nt[nt[xx.id]]]=cnt;
    87                 lt[cnt]=lt[lt[xx.id]];nt[cnt]=nt[nt[xx.id]];
    88                 node nw;
    89                 nw.id=cnt;
    90                 nw.x=myabs(w[nt[xx.id]]+w[lt[xx.id]]+w[xx.id]);
    91                 w[cnt]=w[nt[xx.id]]+w[lt[xx.id]]+w[xx.id];
    92                 q.push(nw);
    93             }
    94         }
    95     }
    96     printf("%d
    ",ans);
    97     return 0;
    98 }
    View Code
    给一个sample
    
    in:
    5
    53 -20 3 -27 68
    
    out:
    77
    

    发发表情更健康

    2017-01-14 11:01:57

  • 相关阅读:
    删除字符串前后的空格
    Python中定义“私有”成员变量和成员函数
    linux 线程
    进程虚拟内存模型
    守护进程
    FIFO
    linux 中的 wait 函数和 waitpid 函数
    孤儿进程和僵尸进程
    linux 中的 exec 函数族
    linux中的fork函数
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/6284865.html
Copyright © 2011-2022 走看看