1. 程式人生 > >BZOJ 2288: 【POJ Challenge】生日禮物 堆&&鏈表

BZOJ 2288: 【POJ Challenge】生日禮物 堆&&鏈表

names queue 技術分享 name 個數 tchar c代碼 turn 備份

就是堆+鏈表,十分像 數據備份 對吧?

把相鄰的正數和相鄰的負數合並成一整個正數塊和負數塊,最後只剩一些交替相間的正塊與負塊了吧?

顯然,正塊的個數<=m時,全部選走就獲得了最大權值,否則我們可能需要選一些負塊來獲得最優解。

然而弱不經風的我調了四個小時鏈表和預處理QAQ。。。

千萬不要犯此種錯誤:

    n=g(),m=g();
    for(R i=1;i<=n;++i) a[i]=g();
    vl[cnt]=a[1],pre[0]=0;
    for(R i=2;i<=n;++i) if(sgn(a[i])==sgn(a[i-1])&&sgn(a[i])) vl[cnt]+=a[i];//
,cnt==1?cerr<<"%"<<vl[cnt]<<" ":cerr<<""; else if(sgn(a[i]))vl[++cnt]=a[i],nxt[cnt-1]=cnt,pre[cnt]=cnt-1; nxt[cnt]=0;

上面這種寫法會吧中間有0的同號塊分成兩塊。。。。

AC代碼:

#include<cstdio>
#include<iostream>
#include<queue>
#define R register int
using namespace std;
const int N=100010; int cnt,n,m,pst,neg,tot,ans=0; int a[N],vl[N],pre[N],nxt[N]; bool vis[N]; struct node{ int vl,pos; node() {} node(int vvl,int ppos):vl(vvl),pos(ppos){} bool operator <(const node& y)const {return vl>y.vl;} }; priority_queue<node> q; inline int
g() { R ret=0,fix=1; register char ch; while(!isdigit(ch=getchar())) fix=ch==-?-1:fix; do ret=ret*10+(ch^48); while(isdigit(ch=getchar())); return ret*fix; } inline int abs(int x) {return x>0?x:-x;} signed main() { n=g(),m=g(); for(R i=1;i<=n;++i) { a[i]=g(); if(a[i]>0){pst+=a[i]; neg&&cnt?vl[++cnt]=neg,neg=0:neg=0;} if(a[i]<0){neg+=a[i]; pst?vl[++cnt]=pst,pst=0:pst=0;} } pst?vl[++cnt]=pst:pst=0; for(R i=1;i<=cnt;++i) { q.push(node(abs(vl[i]),i)); vl[i]>0?++tot,ans+=vl[i]:vl[i]=-vl[i]; nxt[i]=i+1,pre[i]=i-1; } nxt[cnt]=0; for(R i=1;i+m<=tot;++i) { register node tmp=q.top();q.pop(); while(vis[tmp.pos]&&!q.empty()) tmp=q.top(),q.pop(); if(vis[tmp.pos]) break; ans-=tmp.vl; if(q.empty()) break; R pos=tmp.pos; if(!pre[pos]) vis[nxt[pos]]=vis[pos]=true,pre[nxt[nxt[pos]]]=0; else if(!nxt[pos]) vis[pre[pos]]=vis[pos]=true,nxt[pre[pre[pos]]]=0; else { vis[pre[pos]]=vis[nxt[pos]]=true; tmp.vl=vl[pos]=vl[pre[pos]]+vl[nxt[pos]]-vl[pos]; if(nxt[nxt[pos]]) pre[nxt[nxt[pos]]]=pos; if(pre[pre[pos]]) nxt[pre[pre[pos]]]=pos; pre[pos]=pre[pre[pos]],nxt[pos]=nxt[nxt[pos]]; q.push(tmp); } } printf("%d\n",ans); }


2019.04.06

技術分享圖片

BZOJ 2288: 【POJ Challenge】生日禮物 堆&&鏈表