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),含义如上所述。
接下来一行n个整数,第i个整数si(0<=si<=1e9)表示睡觉的愉悦值。
接下来一行n个整数,第i个整数ei(0<=ei<=1e9)表示打隔膜的愉悦值。
Output
第一行输出最大的愉悦值。
接下来一行输出一个长度为n的字符串
第i个字符为E则代表第i小时在打隔膜,第i个字符为S则代表第i个小时在睡觉。
将每个点和每个长度D的区间看作边,限制条件看作流量上下界,差分建图,无源汇最大费用费用流
#include<cstdio> #include<queue> typedef long long i64; const int 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; }