1. 程式人生 > >BZOJ2288:[POJ Challenge]生日禮物——題解

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

AD you struct zoj per 生日禮物 itl ostream 縮進

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

ftiasch 18歲生日的時候,lqp18_31給她看了一個神奇的序列 A1, A2, ..., AN. 她被允許選擇不超過 M 個連續的部分作為自己的生日禮物。

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

這題很像BZOJ1150:[APIO/CTSC2007]數據備份,但如果沒有做過的話其實也不要緊。

參考:https://www.cnblogs.com/zyfzyf/p/4114774.html感覺hzwer博客不是很好懂。

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

如果當前的正數個數<=m顯然就求一遍和即可。

如果>m的話就有兩種選擇了:

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

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

我們發現這兩個操作都是在原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/ +

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

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