zoukankan      html  css  js  c++  java
  • 【链表】BZOJ 2288: 【POJ Challenge】生日礼物

    2288: 【POJ Challenge】生日礼物

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 382  Solved: 111
    [Submit][Status][Discuss]

    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

      先把相邻同号元素合并。
      如果能够全选正数就全选。。
      把所有数的绝对值入堆选前(正数个数-可选最大集合数个).
      选正数的意义-->不选该数
      选负数-->合并两边的正数
      每次减掉堆顶元素的fabs即可。
      和1150差不多的堆+链表
     1 #include<cstdio>
     2 #include<cstring>
     3 #include<cmath>
     4 #include<algorithm>
     5 #include<queue>
     6 
     7 #define maxn 100001
     8 
     9 inline int in()
    10 {
    11     int x=0,f=1;char ch=getchar();
    12     while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    13     if(ch=='-')f=-1,ch=getchar();
    14     while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    15     return f*x;
    16 }
    17 
    18 struct node{
    19     int x,c,ac;
    20     bool operator<(const node &A)const{
    21         return ac>A.ac;
    22     }
    23 };
    24 
    25 using namespace std;
    26 
    27 priority_queue<node>q;
    28 
    29 int n,k,a[maxn*5],sum=0,pre[maxn*5],next[maxn*5],nowa[maxn*5],tot=0,ss=0;
    30 
    31 bool vis[maxn*5];
    32 
    33 void solve()
    34 {
    35     int size=tot+1;
    36     for(int i=1;i<=tot;i++)q.push((node){i,nowa[i],fabs(nowa[i])});
    37     for(int i=1;i<=ss;i++)
    38     {
    39         node Top=q.top();q.pop();
    40         while(vis[Top.x])Top=q.top(),q.pop();
    41         if(!pre[Top.x])
    42         {
    43             if(Top.c<0){i--;}
    44             else{sum-=Top.ac;}
    45             vis[Top.x]=1;
    46             pre[next[Top.x]]=0;
    47             continue;
    48         }
    49         else if(next[Top.x]==tot+1)
    50         {
    51             if(Top.c<0){i--;}
    52             else{sum-=Top.ac;}
    53             vis[Top.x]=1;
    54             next[pre[Top.x]]=tot+1;
    55             continue;
    56         }
    57         node New;
    58         sum-=Top.ac;
    59         New.c=nowa[pre[Top.x]]+nowa[next[Top.x]]+Top.c;
    60         New.x=++size;
    61         nowa[size]=New.c;
    62         next[New.x]=next[next[Top.x]],pre[next[New.x]]=New.x;
    63         pre[New.x]=pre[pre[Top.x]],next[pre[New.x]]=New.x;
    64         vis[Top.x]=vis[pre[Top.x]]=vis[next[Top.x]]=1;
    65         New.ac=fabs(New.c);
    66         q.push(New);
    67     }
    68 }
    69 
    70 void Pre()
    71 {
    72     tot=1;
    73     for(int i=1;i<=n;i++)
    74     {
    75         if(!a[i])continue;
    76         else if(!nowa[tot])nowa[tot]=a[i];
    77         else{
    78             if(nowa[tot]>0&&a[i]>0)nowa[tot]+=a[i];
    79             else if(nowa[tot]<0&&a[i]<0)nowa[tot]+=a[i];
    80             else nowa[++tot]=a[i];
    81         }
    82     }
    83     for(int i=1;i<=tot;i++)next[i]=i+1,pre[i]=i-1;
    84     next[0]=1,pre[tot+1]=tot;
    85 }
    86 
    87 int main()
    88 {
    89     n=in();k=in();
    90     for(int i=1;i<=n;i++)a[i]=in();
    91     Pre();
    92     for(int i=1;i<=tot;i++)if(nowa[i]>0)ss++,sum+=nowa[i];
    93     if(ss<=k){printf("%d",sum);return 0;}
    94     ss-=k;
    95     solve();
    96     printf("%d",sum);
    97     return 0;
    98 }
    View Code
     
  • 相关阅读:
    最小生成树+BFS J
    Noip 2016
    舒适的路线 (code[vs] 1001)
    拦截导弹 (加了神奇的位运算)
    逃出克隆岛 (codevs 2059)
    回家(洛谷 P1592)
    热浪
    城堡
    笔记 (一道正解思路巧妙的题)
    脱水缩合
  • 原文地址:https://www.cnblogs.com/tuigou/p/4868127.html
Copyright © 2011-2022 走看看