bzoj 4842: [Neerc2016]Delight for a Cat
阿新 • • 發佈:2017-07-05
cst des inf rip 小朋友 clas 最大 一行 return
接下來一行n個整數,第i個整數si(0<=si<=1e9)表示睡覺的愉悅值。
接下來一行n個整數,第i個整數ei(0<=ei<=1e9)表示打隔膜的愉悅值。
Description
ls是一個特別墮落的小朋友,對於n個連續的小時,他將要麽睡覺要麽打隔膜,一個小時內他不能既睡覺也打隔膜 ,因此一個小時內他只能選擇睡覺或者打隔膜,當然他也必須選擇睡覺或打隔膜,對於每一個小時,他選擇睡覺或 打隔膜的愉悅值是不同的,對於第i個小時,睡覺的愉悅值為si,打隔膜的愉悅值為ei,同時又有一個奧妙重重的 規定:對於任意一段連續的k小時,ls必須至少有t1時間在睡覺,t2時間在打隔膜。那麽ls想讓他獲得的愉悅值盡 量大,他該如何選擇呢?Input
第一行四個整數,n,k(1<=k<=n<=1000),t1,t2(0<=t1,t2<=k;t1+t2<=k),含義如上所述。Output
第一行輸出最大的愉悅值。 接下來一行輸出一個長度為n的字符串 第i個字符為E則代表第i小時在打隔膜,第i個字符為S則代表第i個小時在睡覺。 將每個點和每個長度D的區間看作邊,限制條件看作流量上下界,差分建圖,無源匯最大費用費用流#include<cstdio> #include<queue> typedef long long i64; constint N=50007; const i64 inf=1ll<<60; int n,k,L,R,as[N],bs[N]; int S,T,es[N],enx[N],ev[N],ec[N],e0[N],ep=2,pe[N]; i64 l[N],ans=0; bool in[N]; std::queue<int>q; void ae(int a,int b,int v,int c){ if(!v)return; es[ep]=b;enx[ep]=e0[a];ev[ep]=v;ec[ep]=c;e0[a]=ep++; es[ep]=a;enx[ep]=e0[b];ev[ep]=0;ec[ep]=-c;e0[b]=ep++; } void mins(int&a,int b){if(a>b)a=b;} bool sp(){ for(int i=1;i<=T;++i)l[i]=-inf; l[S]=0; q.push(S); while(q.size()){ int w=q.front();q.pop(); for(int i=e0[w];i;i=enx[i])if(ev[i]){ int u=es[i]; if(l[u]<l[w]+ec[i]){ l[u]=l[w]+ec[i]; pe[u]=i; if(!in[u])in[u]=1,q.push(u); } } in[w]=0; } if(l[T]>-inf){ int f=100000; for(int w=T,e;w!=S;w=es[e^1]){ e=pe[w]; mins(f,ev[e]); } for(int w=T,e;w!=S;w=es[e^1]){ e=pe[w]; ev[e]-=f; ev[e^1]+=f; } ans+=l[T]*f; return 1; } return 0; } int ee[N]; int main(){ scanf("%d%d%d%d",&n,&k,&L,&R); R=k-R; for(int i=1;i<=n;++i)scanf("%d",as+i); for(int i=1;i<=n;++i)scanf("%d",bs+i); S=n-k+3;T=S+1; for(int i=1;i<=n-k+1;++i)ae(i,i+1,R-L,0); ae(1,T,L,0); ae(S,n-k+2,L,0); for(int i=1;i<=n;++i){ ans+=bs[i]; int x=i-k+1,y=i+1; if(x<1)x=1; mins(y,n-k+2); int c=as[i]-bs[i]; if(c<=0)ee[i]=ep,ae(y,x,1,c); else{ ae(y,T,1,0); ae(S,x,1,c); ee[i]=ep; ae(x,y,1,-c); } } while(sp()); printf("%lld\n",ans); for(int i=1;i<=n;++i){ int c=as[i]-bs[i]; putchar((c<=0)==(!ev[ee[i]])?‘S‘:‘E‘); } return 0; }
bzoj 4842: [Neerc2016]Delight for a Cat