bzoj4842

这是一道网络流的题(大家都看出来了吧)

首先我们简化一下题目,选出最关键的部分(就是知道什么和要求什么,还有条件)

我们在这里把睡觉设为0,至少有t0时间在睡觉,把打隔膜设为1,至少t2时间在打隔膜(方便下面描述)

这样的话就转换成了一个序列问题 ,数列上的点可以选为0或1,第i个位置选0有si的收益,选1有ei的收益,长度为k的序列里至少有t0个0和t1个1。求如何填数才能令这个序列达的收益最大,输出最大收益和填数方案。

样例就不用解释了吧,大家都懂。

假设所有点都选了0,操作由赋值0或1改为将哪些0变为1后更优,每一个0变为1后都有ei-si的收益,一个长度为k的区间内至少有t1个1,定为下界L=t1,至多有k-t0个1(至少有t0个0)定为上界U,(是有上下界的网络流的题!!不过正解不是那样)这样变换后可以试操作更简单。

既然是网络流的,我们考虑怎么建图,一看是一个序列,先把序列上的点依次连接起来S连向1,n连向T,中间的i连向i+1;

然后步入正题,看看本题应该怎么做,参考一下下图:

先只考虑有上界的问题

对于每个点i,我们将它像i+k号点连一条边,表示选了这个点(0改为1),将这一点的流量分走,分向下一个区间,剩下的流量就 -1  表示这个区间内能改的点的个数-1。

将S流向1 的边流量设定为上界U,这样可以保证每个k区间的流量都<=上界。这样就能控制住每个区间内最多分出去U的流量,就是说最多选上界个点;

再考虑下界,就是最少选L个1;也就是说要让这个区间内最少流出L的流量,那么剩下的流量最多就只能流U-L了。所以我们把每个区间末尾的那个边的流量定为U-L控制最多剩下多少流量。

(大家用各种优美姿势感性理解一下)

还有注意不要全开long long ;

不开long long会爆int ,全开会超时~~~这个东西卡了我一个小时。。

至于怎么输出方案,大家胡乱搞一下就好了。

 #include<iostream>
#include<queue>
#include<bit/stdc++.h>
using namespace std;
#define LL long long
#define C continue
#define B break
#define MAXN 101000
#define inf 100000007
inline LL read()
{
LL x=,f=;
char ch=getchar();
while(ch>''||ch<''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=(x<<)+(x<<)+ch-'';ch=getchar();}
return x*f;
}
int n,k,t0,t1,S,T,lin[MAXN],t=;
int v[MAXN],pre[MAXN],U,L,id[MAXN],S0;
LL aa,d[MAXN],AKAKAKAK[MAXN],a[MAXN],ans=,sum;
int incf[MAXN];
struct adge{
int y,ne,c,v;
}e[*MAXN];
void insert(int xx,int yy,int cc,int vv)
{
e[++t].y=yy;e[t].v=vv;e[t].c=cc;e[t].ne=lin[xx];lin[xx]=t;
e[++t].y=xx;e[t].v=-vv;e[t].c=;e[t].ne=lin[yy];lin[yy]=t;
}queue<int> q;
bool SP_spfa(int st)
{
while(q.size())q.pop();
memset(d,,sizeof(d));
aa=d[];
memset(v,,sizeof(v));
q.push(st),d[st]=,v[st]=;
incf[st]=(<<);
while(q.size())
{
int x=q.front();
q.pop();
v[x]=;
for(int i=lin[x];i;i=e[i].ne)
{
int y=e[i].y;
if(d[y]>d[x]+e[i].v&&e[i].c)
{
d[y]=d[x]+e[i].v;
incf[y]=min(incf[x],e[i].c);
pre[y]=i;
if(!v[y])
{
v[y]=;
q.push(y);
}
}
}
}
if(d[T]==aa) return ;
return ;
}
void Update()
{
int x=T;
while(x!=S)
{
int i=pre[x];
e[i].c-=incf[T];
e[i^].c+=incf[T];
x=e[i^].y;
}
ans+=(LL)d[T]*incf[T];
}
int main()
{
//freopen("www.in","r",stdin);
//freopen("www.out","w",stdout);
n=read(),k=read(),t0=read(),t1=read();
for(int i=;i<=n;++i) AKAKAKAK[i]=read(),sum+=AKAKAKAK[i];
for(int i=;i<=n;++i) a[i]=read()-AKAKAKAK[i];
S=,T=n+;U=k-t0;L=t1;S0=n+;
insert(S,S0,U,);
for(int i=;i<=n;++i)
{
/*insert(i,min(i+k,T),1,-a[i]);
if(i<k) insert(i,i+1,inf,0);
else insert(i,i+1,U-L,0);*/
if(i<=k) insert(S0,i,inf,);
insert(i,min(i+,T),U-L,);
insert(i,min(i+k,T),,-a[i]);
id[i]=t;
}
while(SP_spfa(S))Update();
cout<<sum-ans<<endl;
for(int i=;i<=n;++i) {
if(e[id[i]^].c) putchar('S');
else putchar('E');
}
//cout<<s<<endl;
return ;
}

代码

bzoj4842: [Neerc2016]Delight for a Cat的更多相关文章

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

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

  2. 【BZOJ4842】[Neerc2016]Delight for a Cat 线性规划+费用流

    [BZOJ4842][Neerc2016]Delight for a Cat Description ls是一个特别堕落的小朋友,对于n个连续的小时,他将要么睡觉要么打隔膜,一个小时内他不能既睡觉也打 ...

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

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

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

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

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

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

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

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

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

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

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

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

  9. bzoj4842 Delight for a Cat

    题意:n天内你每天可以s或者e,分别有一定的收益. 每连续k天中s的天数要大于ds,e的天数要大于de,求最大收益. 解:费用流解线性规划. 先假设全部选e,然后一天s的收益为si - ei ai表示 ...

随机推荐

  1. Borg Maze(BFS+MST)

    Borg Maze http://poj.org/problem?id=3026 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions ...

  2. Python深度学习之安装theano(windows)

    前方预警:windows的坑太多了,抛弃用linux吧 安装theano,提前清空自己的python环境吧,坑太多了,anaconda会自动安装path 一,首先安装python包管理anaconda ...

  3. [Selenium] 怎样判断是否适合自动化测试

    实施自动化测试前需要对软件开发过程进行分析,以观察其是否适合使用自动化测试.通常需要满足以下条件: 1)需求变动不频繁 2)项目周期足够长 3)自动化测试脚本可重复使用 4)手工测试无法完成或者需要大 ...

  4. [Selenium]Click element under a hidden element

    Description: Find out the DDL in Treegrid, but cannot click on it.Because the element is under a hid ...

  5. Centos 7 安装和配置Redis

    一. 安装 操作系统:Centos 7. 最小化安装 redis版本: 4.0.6 服务器地址:*** 第一步:下载redis安装包(如果有新的,下载最新的redis安装包) wget http:// ...

  6. win10 跳过max path 260限制

    参考: https://www.howtogeek.com/266621/how-to-make-windows-10-accept-file-paths-over-260-characters/ 注 ...

  7. BUG记忆

      保留两位小数 <fmt:formatNumber value="${list.avgAssessment}" pattern="#.00#"/> ...

  8. invoke方法

    主要是为了类反射,这样你可以在不知道具体的类的情况下,根据配置的字符串去调用一个类的方法.在灵活编程的时候非常有用.很多框架代码都是这样去实现的.但是一般的编程,你是不需要这样做的,因为类都是你自己写 ...

  9. mysql server 自动断开的问题

    今天发现mysql的一个问题,当跑update语句的时候,mysql 服务会自动断掉,无论用 phpmyadmin, navicat , mysql workbench 甚至用 mysql命令行效果一 ...

  10. chrome一个奇怪的问题

    我去........... 这牢骚发完了才发现,  多谢了个e 呃................. ================================= 晚上用bootstrap搭建一 ...