BZOJ2288:[POJ Challenge]生日禮物——題解

https://www.lydsy.com/JudgeOnline/problem.php?id=2288php

ftiasch 18歲生日的時候,lqp18_31給她看了一個神奇的序列 A1A2, ..., AN. 她被容許選擇不超過 M 個連續的部分做爲本身的生日禮物。html

天然地,ftiasch想要知道選擇元素之和的最大值。你能幫助她嗎?node

 

這題很像BZOJ1150:[APIO/CTSC2007]數據備份,但若是沒有作過的話其實也沒關係。ios

參考:http://www.javashuo.com/article/p-rxegfodm-er.html感受hzwer博客不是很好懂。git

咱們首先將相同符號的點縮起來,去掉首末的負結點,而後思考。post

若是當前的正數個數<=m顯然就求一遍和便可。spa

若是>m的話就有兩種選擇了:code

1.忍痛割愛棄掉一個正數。htm

2.選擇一個負數,將兩旁正數連同負數一塊兒縮進來。blog

咱們發現這兩個操做都是在原ans的基礎上支付咱們選擇的點代價的,所以咱們支付的代價越少越好,故咱們將點權的abs放入小根堆裏,每次拿出來以後和兩邊的點縮起來便可。

#include<map>
#include<cmath>
#include<stack>
#include<queue>
#include<cstdio>
#include<cctype>
#include<vector>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef pair<int,int>pii;
#define fi first
#define se second
const int N=1e5+5;
const int INF=1e9+5;
inline int read(){
    int X=0,w=0;char ch=0;
    while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
    while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
    return w?-X:X;
}
struct node{
    int x,y;
    node(int xx=0,int yy=0){
        x=xx;y=yy;
    }
    bool operator <(const node &b)const{
        return abs(x)>abs(b.x);
    }
};
priority_queue<node>q;
int n,m,cnt,tmp,a[N],b[N],pre[N],nxt[N];
int main(){
    n=read(),m=read();
    for(int i=1;i<=n;i++){
        a[++tmp]=read();
        if(!a[tmp])tmp--;
    }
    
    b[++cnt]=a[1];
    for(int i=2;i<=tmp;i++){
        if((a[i]>0&&a[i-1]>0)||(a[i]<0&&a[i-1]<0))b[cnt]+=a[i];
        else{
            if(cnt==1&&b[cnt]<0)cnt--;
            b[++cnt]=a[i];
        }
    }
    if(b[cnt]<0)cnt--;
    
    int ans=0,tot=0;
    for(int i=1;i<=cnt;i++){
        if(b[i]>0)ans+=b[i],tot++;
        q.push(node(b[i],i));
    }
    
    for(int i=0;i<=cnt+1;i++)pre[i]=i-1,nxt[i]=i+1;
    pre[0]=0;nxt[cnt+1]=cnt+1;
    b[0]=b[cnt+1]=-INF;
    
    while(tot>m){
        node p=q.top();q.pop();
        if(b[p.y]!=p.x)continue;
        ans-=abs(p.x);
        b[p.y]=b[pre[p.y]]+b[nxt[p.y]]+p.x;
        b[pre[p.y]]=b[nxt[p.y]]=-INF;
        q.push(node(b[p.y],p.y));
        pre[p.y]=pre[pre[p.y]];nxt[pre[p.y]]=p.y;
        nxt[p.y]=nxt[nxt[p.y]];pre[nxt[p.y]]=p.y;
        tot--;
    }
    printf("%d\n",ans);
    return 0;
}

+++++++++++++++++++++++++++++++++++++++++++

+本文做者:luyouqi233。               +

+歡迎訪問個人博客:http://www.cnblogs.com/luyouqi233/ +

+++++++++++++++++++++++++++++++++++++++++++

相關文章
相關標籤/搜索