ccz181078

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: :: 管理 ::

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;
}

 

posted on 2017-07-05 18:13  nul  阅读(440)  评论(0编辑  收藏  举报