【2017山东day7】养猫
【2017山东day7】养猫
Description
  你养了一只猫,为了让它快乐地成长,你需要合理地安排它每天的作息时间。假设一天分为$ n \(个时刻,猫在每个时刻要么是吃东西,要么是睡觉。在第\) i $个时刻,假如猫是去吃东西,那么它能获得愉悦值 \(ei\),假如是去睡觉,那么能获得的愉悦值为 \(si\)。
  猫要成长,不仅仅需要快乐,还需要健康的作息。经过研究,对于每一个连续的长度为 k 的作息区间,即所有的时刻区间$ [i,i+k−1],1≤i≤n−k+1$,猫都要至少有 \(ms\)的时刻用来睡觉,$me $的时刻用来吃东西,这样猫才能健康成长。
  现在你想合理地安排一天中的这 n个时刻,使得猫在能健康成长的前提下,获得尽量多的愉悦值。
Input
  第一行四个整数 \(n,k,ms,me\)。
  第二行包含\(n\)个整数,代表\(si\)。
  第三行包含\(n\)个整数,代表\(ei\)。
Output
  第一行一个整数,代表猫能获得的愉悦值。
  第二行 n 个字符,可以为 S 或 E,代表猫在某个时刻是在睡觉(S)还是在吃东西(E)。
Sample Input
5 4 2 2
4 8 6 2 2
4 6 9 6 0
Sample Output
29
SSEES
参考博客https://www.cnblogs.com/CQzhangyu/p/7894559.html
我们先全部吃。
\(y_i\)和\(z_i\)是我们设出来的辅助变量,使得\(\leq ,\ge\)变成了\(=\)。
x_2+x_3+...+x_{k+1}=k-t_2-z_2\\
...\\
x_{n-k+1}+x_{n-k+2}+...+x_n=t_1+y_{n-k+1}\\
x_{n-k+1}+x_{n-k+2}+...+x_n=k-t_2-z_{n-k+1}
\end{cases}
\]
我们保留第\(1\)个和最后一个方程,其他的方程与前一个做差分,得到:
x_1+x_2+...+x_k=t_1+y_1\\
k-t_2=x_{n-k+1}+x_{n-k+2}+...+x_n+z_{n-k+1}\\
y_i+z_i=k-t_1-t_2(1\leq i\leq n-k+1)\\
x_{i+k}+k-t_1-t_2=x_i+z_i+y_{i+1}(1\leq i\leq n-k)\\
\end{cases}
\]
我们整理一下,使得每个未知量恰好在左边出现一次,恰好在右边出现一次。
我们拿方程作为节点,假设方程左边的常数为\(LC\),右边的常数为\(RC\),我们连\((S,i,LC,0),(i,T,RC,0)\)。(最后一维表示费用)。
然后对于未知量\(x_i\),假设它出现在\(a\)的左边,\(b\)的右边,我们连\((b,a,1,S_i-E_i)\)。
跑最大费用最大流。
我开始时犯了常识错误,即使最长路为负也要加上贡献,因为我们要先保证最大流。
代码:
#include<bits/stdc++.h>
#define ll long long
#define N 4005
using namespace std;
inline int Get() {int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}while('0'<=ch&&ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}return x*f;}
int n,k,t1,t2;
ll S[N],E[N],w[N];
int SS,TT;
struct road {
	int to,next;
	ll f,c;
}s[N<<3];
int h[N],cnt=1;
void add(int i,int j,int f,int c) {
	s[++cnt]=(road) {j,h[i],f,c};h[i]=cnt;
	s[++cnt]=(road) {i,h[j],0,-c};h[j]=cnt;
}
ll ans;
queue<int>q;
bool in[N];
ll dis[N];
int fr[N],e[N];
bool spfa(int S,int T) {
	memset(dis,-0x3f,sizeof(dis));
	dis[S]=0;
	q.push(S);
	while(!q.empty()) {
		int v=q.front();q.pop();
		in[v]=0;
		for(int i=h[v];i;i=s[i].next) {
			int to=s[i].to;
			if(s[i].f&&dis[to]<dis[v]+s[i].c) {
				dis[to]=dis[v]+s[i].c;
				fr[to]=v;
				e[to]=i;
				if(!in[to]) {
					in[to]=1;
					q.push(to);
				}
			}
		}
	}
	if(dis[T]<-1e9) return 0;
	ll maxflow=1e9;
	for(int i=T;i;i=fr[i]) {
		maxflow=min(maxflow,s[e[i]].f);
	}
	ans+=maxflow*dis[T];
	for(int i=T;i;i=fr[i]) {
		s[e[i]].f-=maxflow;
		s[e[i]^1].f+=maxflow;
	}
	return 1;
}
int edge_id[N];
int main() {
	n=Get(),k=Get(),t1=Get(),t2=Get();
	for(int i=1;i<=n;i++) S[i]=Get();
	for(int i=1;i<=n;i++) E[i]=Get();
	for(int i=1;i<=n;i++) ans+=E[i];
	for(int i=1;i<=n;i++) w[i]=S[i]-E[i];
	TT=2*n+2;
	add(1,TT,t1,0);
	add(SS,2,k-t2,0);
	for(int i=1;i<=n-k+1;i++) add(i+2,TT,k-t1-t2,0);
	for(int i=1;i<=n-k;i++) {
		add(SS,i+n-k+3,k-t1-t2,0);
	}
	for(int i=1;i<=k;i++) {
		edge_id[i]=cnt+1;
		if(i>=n-k+1) add(2,1,1,w[i]);
		else add(n-k+3+i,1,1,w[i]);
	}
	for(int i=1;i<=n-k;i++) {
		edge_id[i+k]=cnt+1;
		if(i+k>=n-k+1) add(2,i+n-k+3,1,w[i+k]);
		else add(i+n+3,i+n-k+3,1,w[i+k]);
	}
	add(1,3,1e9,0);
	for(int i=1;i<=n-k;i++) add(i+n-k+3,i+3,1e9,0);
	for(int i=1;i<=n-k;i++) add(i+n-k+3,i+2,1e9,0);
	add(2,n-k+3,1e9,0);
	while(spfa(SS,TT));
	cout<<ans<<"\n";
	for(int i=1;i<=n;i++) {
		if(s[edge_id[i]].f) cout<<"E";
		else cout<<"S";
	}
	return 0;
}
												
											【2017山东day7】养猫的更多相关文章
- 「2017 山东三轮集训 Day7 解题报告
		
「2017 山东三轮集训 Day7」Easy 练习一下动态点分 每个点开一个线段树维护子树到它的距离 然后随便查询一下就可以了 注意线段树开大点... Code: #include <cstdi ...
 - 【LOJ6077】「2017 山东一轮集训 Day7」逆序对 生成函数+组合数+DP
		
[LOJ6077]「2017 山东一轮集训 Day7」逆序对 题目描述 给定 n,k ,请求出长度为 n的逆序对数恰好为 k 的排列的个数.答案对 109+7 取模. 对于一个长度为 n 的排列 p ...
 - 2017 山东二轮集训 Day7 国王
		
2017 山东二轮集训 Day7 国王 题目大意 给定一棵树,每个点有黑白两种颜色,定义一条简单路径合法当且仅当路径上所有点黑色与白色数量相等,求有多少非空区间 \([L,R]\) ,使得所有编号 \ ...
 - loj #6077. 「2017 山东一轮集训 Day7」逆序对
		
#6077. 「2017 山东一轮集训 Day7」逆序对 题目描述 给定 n,k n, kn,k,请求出长度为 n nn 的逆序对数恰好为 k kk 的排列的个数.答案对 109+7 10 ^ 9 ...
 - 【LOJ6067】【2017 山东一轮集训 Day3】第三题 FFT
		
[LOJ6067][2017 山东一轮集训 Day3]第三题 FFT 题目大意 给你 \(n,b,c,d,e,a_0,a_1,\ldots,a_{n-1}\),定义 \[ \begin{align} ...
 - Loj #6069. 「2017 山东一轮集训 Day4」塔
		
Loj #6069. 「2017 山东一轮集训 Day4」塔 题目描述 现在有一条 $ [1, l] $ 的数轴,要在上面造 $ n $ 座塔,每座塔的坐标要两两不同,且为整点. 塔有编号,且每座塔都 ...
 - Loj #6073.「2017 山东一轮集训 Day5」距离
		
Loj #6073.「2017 山东一轮集训 Day5」距离 Description 给定一棵 \(n\) 个点的边带权的树,以及一个排列$ p\(,有\)q $个询问,给定点 \(u, v, k\) ...
 - Loj 6068. 「2017 山东一轮集训 Day4」棋盘
		
Loj 6068. 「2017 山东一轮集训 Day4」棋盘 题目描述 给定一个 $ n \times n $ 的棋盘,棋盘上每个位置要么为空要么为障碍.定义棋盘上两个位置 $ (x, y),(u, ...
 - 「2017 山东一轮集训 Day5」苹果树
		
「2017 山东一轮集训 Day5」苹果树 \(n\leq 40\) 折半搜索+矩阵树定理. 没有想到折半搜索. 首先我们先枚举\(k\)个好点,我们让它们一定没有用的.要满足这个条件就要使它只能和坏 ...
 
随机推荐
- log4.net 自定义日志文件名称
			
插件化项目中,遇到这样一个需求,每个插件 或者每个方法 一个日志文件,方便后期错误排查 源码地址: https://github.com/xlb378917466/SharpHttpServerCas ...
 - 23.QT记事本
			
描述 主要功能有: 新建,打开,保存,另存为,打印, 编辑,撤销,,拖放,xml配置文件读写,字体更改,查找替换 菜单栏,工具栏,状态栏的实现 如下图所示: 效果如下所示: 源码下载地址: htt ...
 - 23.C++- 继承的多种方式、显示调用父类构造函数、父子之间的同名函数、virtual虚函数
			
上章链接: 22.C++- 继承与组合,protected访问级别 继承方式 继承方式位于定义子类的”:”后面,比如: class Line : public Object //继承方式是publi ...
 - Java集合性能分析-疯狂Java讲义
			
一.各Set实现类的性能分析 HashSet和TreeSet是Set的两个典型实现.HashSet的性能总是比TreeSet好(特别是最常用的添加.查询元素等操作),因为TreeSet需要额外的红黑树 ...
 - <a>标签的特殊和文本的样式
			
a是特殊的,要改变a里面的颜色,必须直接给a设置,给a的父级设置不行 属性继承:明明是父级上的的设置样式,结果后代标签也跟着发生变化,这就叫做属性继承. Html 标记语言, 不是编程语言.说白了就是 ...
 - Python 语法笔记
			
1.else与while结合 while a>0: pass else: pass #当a<=0时执行 2.with语法,无需关闭文件,python自动关闭 with open('a.tx ...
 - JavaScript是如何工作的:Web Workers的构建块 + 5个使用他们的场景
			
摘要: 理解Web Workers. 原文:JavaScript是如何工作的:Web Workers的构建块 + 5个使用他们的场景 作者:前端小智 Fundebug经授权转载,版权归原作者所有. 这 ...
 - 聊聊ES7与ES8特性
			
译者按: 转眼ES6发布2年了,是时候了解一下ES7与ES8特性了! 原文: ES7 and ES8 Features 译者: Fundebug 为了保证可读性,本文采用意译而非直译,并且对源代码进行 ...
 - IO学习二(节点流)
			
1.流的分类 按照数据流向的不同:输入流和输出流 按照处理数据的单位不同:字节流((非文本文件)视频.音频.图像).字符流(文本文件) 按照角色的不同:节点流和处理流 2.IO体系 抽象基类 节点流 ...
 - bootstrap网站后台从设计到开发
			
前言 毕业后在一家小公司找的工作是做前端,小公司必须要身兼多职,会多门技术,所以为了工作需要自学ps,做过微信运营,后来为了做erp管理系统,又开始学习c# ,之后公司有新项目要用wpf ,我又开始学 ...