zoukankan      html  css  js  c++  java
  • bzoj2288【POJ Challenge】生日礼物*

    bzoj2288【POJ Challenge】生日礼物

    题意:

    给一个序列,求不超过m个连续的部分,使元素和最大。序列大小≤100000

    题解:

    先把连续的正数和负数合并起来,接着如果正数个数小于m则全选,否则需要确定去掉那个正数或合并哪个正数。初始ans设为所有正数和,将所有的数按绝对值大小放入堆中,然后重复m-正数个数操作:每次选取绝对值最小的数,如果是负数且它在边界处则重新选,否则将这个数删除并将两边的数合并,同时ans-=该数绝对值。该操作的意义在于:如果删去的是正数表示不选它,否则表示选这个负数以将左右的的正数合并起来。类似于1150,我用链表和STLset维护这个过程。

    代码:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include <set>
     5 #define inc(i,j,k) for(int i=j;i<=k;i++)
     6 #define maxn 100010
     7 using namespace std;
     8 
     9 inline int read(){
    10     char ch=getchar(); int f=1,x=0;
    11     while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
    12     while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    13     return f*x;
    14 }
    15 int n,m,a[maxn],b[maxn],tot,ans;
    16 struct sn{
    17     int pos,v;
    18     bool operator < (const sn &x)const{return v!=x.v?v<x.v:pos<x.pos;}
    19 };
    20 set<sn>s;
    21 struct nd{int v,l,r; bool bit;}; nd nds[maxn];
    22 int main(){
    23     n=read(); m=read(); inc(i,1,n)b[i]=read();
    24     int last=0; inc(i,1,n){
    25         if(b[i]==0)continue; if(!last||(last>0^b[i]>0))a[++tot]=b[i];else a[tot]+=b[i]; last=b[i];
    26     }
    27     n=tot; tot=0; inc(i,1,n)if(a[i]>0)tot++,ans+=a[i];
    28     if(tot>m){
    29         inc(i,1,n){s.insert((sn){i,abs(a[i])}); nds[i]=(nd){abs(a[i]),i-1,i+1>n?0:i+1,a[i]>0};}
    30         inc(i,1,tot-m){
    31             set<sn>::iterator xx; int x;
    32             while(1){
    33                 xx=s.begin(); x=xx->pos; s.erase(xx);
    34                 if((!nds[x].l||!nds[x].r)&&!nds[x].bit){
    35                     if(!nds[x].l)nds[nds[x].r].l=0; if(!nds[x].r)nds[nds[x].l].r=0;
    36                 }else break;
    37             }
    38             ans-=nds[x].v;
    39             if(!nds[x].l&&!nds[x].r)continue;
    40             else if(!nds[x].r)nds[nds[x].l].r=0;
    41             else if(!nds[x].l)nds[nds[x].r].l=0;
    42             else{
    43                 nds[x].v=nds[nds[x].l].v+nds[nds[x].r].v-nds[x].v; nds[x].bit=nds[nds[x].l].bit;
    44                 xx=s.find((sn){nds[x].l,nds[nds[x].l].v}); s.erase(xx);
    45                 xx=s.find((sn){nds[x].r,nds[nds[x].r].v}); s.erase(xx);
    46                 s.insert((sn){x,nds[x].v});
    47                 nds[x].l=nds[nds[x].l].l; nds[x].r=nds[nds[x].r].r; nds[nds[x].l].r=x; nds[nds[x].r].l=x;
    48             }
    49         }
    50     }
    51     printf("%d",ans); return 0;
    52 }

    20160905

  • 相关阅读:
    闰年判断
    加法乘法模拟
    unordered_set构造 count_if函数
    写了又忘的层序遍历
    SQL Server 2000+ MS WIN2003群集服务配置
    解决IE8在vs2005下不能调试的问题.
    java邮件发送小实例
    异常:org.hibernate.AnnotationException: @Temporal should only be set on a java.util.Date or java.util.Calendar property
    异常:IOException while loading persisted sessions: java.io.EOFException
    异常:org.hibernate.cache.NoCachingEnabledException: Secondlevel cache is not enabled for usage [hibernate.cache.use_second_level_cache | hibernate.cach
  • 原文地址:https://www.cnblogs.com/YuanZiming/p/5861750.html
Copyright © 2011-2022 走看看