【BZOJ4842】[Neerc2016]Delight for a Cat

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个小时在睡觉。

Sample Input

10 4 1 2
1 2 3 4 5 6 7 8 9 10
10 9 8 7 6 5 4 3 2 1

Sample Output

69
EEESESEESS

题解:我们先令所有时间都打隔膜,于是在i时刻睡觉的收益就变成了si-ei。我们令第i时刻是否睡觉的状态为xi(xi=0或1),那么限制条件就变成了如下不等式:$t_1 \le x_i+x_{i+1}+...+x_{i+k-1} \le k-t_2$。我们想要最大化$\sum x_i*(s_i-e_i)$,这显然就变成了一个线性规划问题。如何处理线性规划问题?列单纯形表。

然而今天还是去学了用费用流解线性规划的方法。我们先将不等式转化成标准型,即加入新变量y,z($y,z \in [0,+ \infty ]$)使不等式变成等式:$t_1+y_i=x_i+x_{i+1}+...+x_{i+k-1}=k-t_2-z_i$,接着列出方程组:

$\begin{cases}x_1+x_2+...+x_k=t_1+y_1\\ x_1+x_2+...+x_k=k-t_2-z_1\\ x_2+x_3+...+x_{k+1}=t_1+y_2\\ x_2+x_3+...+x_{k+1}=k-t_2-z_2\\ ...\end{cases}$

根据一个惯用的套路,我们在最下面加入不等式0=0,然后差分,并整理一下:

$\begin{cases}x_1+x_2+...+x_k=t_1+y_1\\ y_1+z_1=(k-t_1-t_2)\\ x_{k+1}+(k-t_1-t_2)=x_2+z_1+y_2\\ y_2+z_2=(k-t_1-t_2)\\ ...\\k-t_2=x_{n-k+1}+x_{n-k+2}+...+x_k+z_{n-k+1}\end{cases}$

我们发现每个变量在等式的左侧和右侧都各出现一次,我们将等式看成点,等式左边看成流出,等式右面看成流入。对于变量x,我们从它流出的点向流入的点连一条边,容量为1费用为si-ei;对于变量y,z,它的容量为$\infty$,费用为0;对于常数项,如果是流出则从该点连向T,流入则从S连向该点,容量为常数项的大小。接着跑最大费用最大流,输出方案时看一下对应的边的容量即可。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
using namespace std;
typedef long long ll;
ll ans,tot;
int n,k,t1,t2,cnt,S,T;
int inq[2010],to[100010],next[100010],flow[100010],pe[2010],pv[2010],head[2010],pos[2010],A[2010],B[2010];
ll cost[100010],dis[2010];
queue<int> q;
inline int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-')f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
return ret*f;
}
inline void add(int a,int b,int c,int d)
{
if(!d) return ;
to[cnt]=b,cost[cnt]=c,flow[cnt]=d,next[cnt]=head[a],head[a]=cnt++;
to[cnt]=a,cost[cnt]=-c,flow[cnt]=0,next[cnt]=head[b],head[b]=cnt++;
}
inline int bfs()
{
memset(dis,0x80,sizeof(dis));
q.push(S),dis[S]=0;
int u,i;
while(!q.empty())
{
u=q.front(),q.pop(),inq[u]=0;
for(i=head[u];i!=-1;i=next[i])
{
if(dis[to[i]]<dis[u]+cost[i]&&flow[i])
{
dis[to[i]]=dis[u]+cost[i],pv[to[i]]=u,pe[to[i]]=i;
if(!inq[to[i]]) inq[to[i]]=1,q.push(to[i]);
}
}
}
return dis[T]>ll(0x8080808080808080ll);
}
int main()
{
n=rd(),k=rd(),t1=rd(),t2=rd();
S=0,T=((n-k+1)<<1)+2;
memset(head,-1,sizeof(head));
int i;
for(i=1;i<=n;i++) A[i]=rd();
for(i=1;i<=n;i++) B[i]=rd(),tot+=B[i];
for(i=1;i<=n;i++) pos[i]=cnt+1,add(max(1,((i-k)<<1)+1),min((i<<1)+1,((n-k+1)<<1)+1),A[i]-B[i],1);
add(S,1,0,t1);
for(i=1;i<=n-k+1;i++)
{
add(i<<1,(i<<1)-1,0,1<<30),add(i<<1,(i<<1)+1,0,1<<30);
add(S,i<<1,0,k-t1-t2);
if(i!=n-k+1) add((i<<1)+1,T,0,k-t1-t2);
}
add(((n-k+1)<<1)+1,T,0,k-t2);
while(bfs())
{
int mf=1<<30;
for(i=T;i!=S;i=pv[i]) mf=min(mf,flow[pe[i]]);
ans+=dis[T]*mf;
for(i=T;i!=S;i=pv[i]) flow[pe[i]]-=mf,flow[pe[i]^1]+=mf;
}
printf("%lld\n",tot+ans);
for(i=1;i<=n;i++)
{
if(flow[pos[i]]) printf("S");
else printf("E");
}
return 0;
}
//2 2 0 0 1 2 2 1

【BZOJ4842】[Neerc2016]Delight for a Cat 线性规划+费用流的更多相关文章

  1. bzoj 4842 [Neerc2016]Delight for a Cat 最小费用最大流,线性规划

    题意:有n个小时,对于第i个小时,睡觉的愉悦值为si,打隔膜的愉悦值为ei,同时对于任意一段连续的k小时,必须至少有t1时间在睡觉,t2时间在打隔膜.如果要获得的愉悦值尽 量大,求最大的愉悦值和睡觉还 ...

  2. 【bzoj4842】[Neerc2016]Delight for a Cat 线性规划与网络流

    题目描述 $n$ 个连续的位置,每个位置可以填入 S 和 E ,第 $i$ 个位置填入 S 可以获得 $s_i$ 的收益,填入 E 可以获得 $e_i$ 的收益.要求每连续的 $k$ 个位置必须包含至 ...

  3. 题解-bzoj1283序列 & bzoj4842 [Neerc2016]Delight for a Cat

    因为这两题有递进关系,所以放一起写 Problem bzoj1283 序列 题意概要:一个长度为 \(n\) 的序列\(\{c_i\}\),求一个子集,使得原序列中任意长度为 \(m\) 的子串中被选 ...

  4. bzoj4842: [Neerc2016]Delight for a Cat

    bzoj4842 这是一道网络流的题(大家都看出来了吧) 首先我们简化一下题目,选出最关键的部分(就是知道什么和要求什么,还有条件) 我们在这里把睡觉设为0,至少有t0时间在睡觉,把打隔膜设为1,至少 ...

  5. 线性规划费用流解法(Bzoj1061: [Noi2008]志愿者招募)

    题面 传送门 Sol 线性规划费用流解法用与求解未知数为非负数的问题 这道题可以列出一堆形如 \(x[i]+x[j]+x[k]+...>=a[p]\) 的不等式 我们强行给每个式子减去一个东西, ...

  6. [bzoj4842][bzoj1283][Neerc2016]Delight for a Cat/序列_线性规划_费用流

    4842: [Neerc2016]Delight for a Cat_1283: 序列 题目大意:ls是一个特别堕落的小朋友,对于n个连续的小时,他将要么睡觉要么打隔膜,一个小时内他不能既睡觉也打隔膜 ...

  7. BZOJ.4842.[NEERC2016]Delight for a Cat(费用流)

    BZOJ 参考这儿. 首先如果一个活动的时间满足条件,那么另一个活动也一定满足.还有就是这题就是费用流没有为什么.不妨假设最初所有时间都用来睡觉,那么我们要对每个\(k\)大小区间选出\([t2,k- ...

  8. bzoj 4842: [Neerc2016]Delight for a Cat

    Description ls是一个特别堕落的小朋友,对于n个连续的小时,他将要么睡觉要么打隔膜,一个小时内他不能既睡觉也打隔膜 ,因此一个小时内他只能选择睡觉或者打隔膜,当然他也必须选择睡觉或打隔膜, ...

  9. bzoj 4842: [Neerc2016]Delight for a Cat【最小费用最大流】

    考试题搞了好久也没懂-- 正解应该是线性规划 https://www.cnblogs.com/CQzhangyu/p/7894559.html 可是不会写啊 如果从网络流的角度来体会大概是这样 htt ...

随机推荐

  1. Java8学习笔记(一)--Lambda表达式

    两个概念 函数式接口 函数式接口就是只显式声明一个抽象方法的接口.为保证方法数量不多不少,java8提供了一个专用注解@FunctionalInterface,这样,当接口中声明的抽象方法多于或少于一 ...

  2. 来自多校的一个题——数位DP+卡位

    n<=1e9就要考虑倍增.矩阵乘法这种了 假设L=0 考虑枚举二进制下,所有X与R的LCP长度,前len高位 对于第len+1位,假设R的这一位是1 如果一个x的这一位是0了,那么后面可以随便填 ...

  3. JMeter 不同线程组间变量传递

    JMeter元件都是有作用域的,而变量大多使用正则表达式提取器,要想在不通过线程组件使用变量参数,则需要设置全部变量 JMeter函数助手就提供了一个函数用于设置全局变量属性,实现的功能类似于在用户自 ...

  4. vegas 为盖斯

    vegas 为盖斯 S键 分割素材U键 分开视频和音频I键渲染开始O渲染结束 默认布局 为盖斯新建项目的参数 剪好后渲染 插入字幕

  5. CMDB资产管理系统开发【day26】:数据正式存入待存区

    1.from表单提交 1.数据提交到哪里呢? 提交到assets/new_assets_approval.html这了 2.Yes, I'm sure提交了什么?          为什么没有下拉框了 ...

  6. python脚本 用sqoop把mysql数据导入hive

    转:https://blog.csdn.net/wulantian/article/details/53064123 用python把mysql数据库的数据导入到hive中,该过程主要是通过pytho ...

  7. django - 总结 - CRM - 知识点

    1.扩展auth_user from django.contrib.auth.models import User,AbstractUser class UserInfo(AbstractUser): ...

  8. tangent space与object space

    3d渲染每个网格(Mesh)的面都可配一个材质(Material),要想在一个面上显示出更多的细节,除了模型做的更精致,还可以使用法线贴图(Normal Texture). 法线向量(Normal V ...

  9. 【webpack】中file-loader和url-loader使用方法

    file-loader 可以指定要复制和放置资源文件的位置,以及如何使用版本哈希命名以获得更好的缓存.此外,这意味着 你可以就近管理图片文件,可以使用相对路径而不用担心部署时 URL 的问题.使用正确 ...

  10. python3: 简单4步骤输出九九乘法表

    如何输出一个九九乘法表,使用python语言,嵌套循环,4行代码就可以实现,瞬间感觉python真的很简单~ 代码: for i in range(1,10): for j in range(1,i+ ...