BZOJ_3550_[ONTAK2010]Vacation&&BZOJ_1283:_序列_网络流解线性规划

Description

给出一个长度为 的正整数序列Ci,求一个子序列,使得原序列中任意长度为 的子串中被选出的元素不超过K(K,M<=100) 个,并且选出的元素之和最大。

Input

第1行三个数N,m,k。 接下来N行,每行一个字符串表示Ci。

Output

最大和。

Sample Input

10 5 3
4 4 4 6 6 6 6 6 4 4

Sample Output

30


设xi为第i个数是否选。

于是我们有n-m+1个方程

$\begin{matrix}
xi\ge 0\\
x1+x2+x3+x4+x5\le K\\
x2+x3+x4+x5+x6\le K\\
x3+x4+x5+x6+x7\le K\\
x4+x5+x6+x7+x8\le K\\
x5+x6+x7+x8+x9\le K\\
x6+x7+x8+x9+x10\le K\\
\end{matrix}$

变成线性等式

$\begin{matrix}
xi\ge 0\\
yi\ge 0\\
x1+x2+x3+x4+x5+y1=K\\
x2+x3+x4+x5+x6+y2=K\\
x3+x4+x5+x6+x7+y3=K\\
x4+x5+x6+x7+x8+y4=K\\
x5+x6+x7+x8+x9+y5=K\\
x6+x7+x8+x9+x10+y6=K\\
\end{matrix}$

差分一下增加一个方程

$\begin{matrix}
xi\ge 0\\
yi\ge 0\\
x1+x2+x3+x4+x5+y1-K=0\\
x6-x1+y2-y1=0\\
x7-x2+y3-y2=0\\
x8-x3+y4-y3=0\\
x9-x4+y5-y4=0\\
x10-x5+y6-y5=0\\
-x6-x7-x8-x9-x10-y6+K=0\\
\end{matrix}$

然后建图跑最大费用最大流。

对于方程,建立n-m+1个点,对于变量x,找到系数为+1的方程位置和系数为-1的方程位置连边(inf,a[i])。

对于y变量连i->i+1(inf,0)。S->1(K,0),n-m+2->T(K,0)。

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 1050
#define M 100050
#define S (n-m+3)
#define T (n-m+4)
#define inf (1<<30)
int head[N],to[M],nxt[M],cnt=1,path[N],dis[N],Q[N],l,r,inq[N],flow[M],val[M];
int n,m,K,a[N];
inline void add(int u,int v,int f,int w) {
to[++cnt]=v; nxt[cnt]=head[u]; head[u]=cnt; flow[cnt]=f; val[cnt]=w;
to[++cnt]=u; nxt[cnt]=head[v]; head[v]=cnt; flow[cnt]=0; val[cnt]=-w;
}
bool spfa() {
memset(dis,0x80,sizeof(dis));
memset(path,0,sizeof(path));
l=r=0; Q[r++]=S; dis[S]=0; inq[S]=1;
while(l!=r) {
int x=Q[l++],i; if(l==T+1) l=0; inq[x]=0;
for(i=head[x];i;i=nxt[i]) {
if(flow[i]&&dis[to[i]]<dis[x]+val[i]) {
dis[to[i]]=dis[x]+val[i];
path[to[i]]=i^1;
if(!inq[to[i]]) {
inq[to[i]]=1; Q[r++]=to[i]; if(r==T+1) r=0;
}
}
}
}
return path[T];
}
void mcmf() {
int minc=0,maxf=0,i;
while(spfa()) {
int nf=1<<30;
for(i=T;i!=S;i=to[path[i]]) {
nf=min(nf,flow[path[i]^1]);
}
for(i=T;i!=S;i=to[path[i]]) {
flow[path[i]]+=nf;
flow[path[i]^1]-=nf;
minc+=nf*val[path[i]^1];
}
maxf+=nf;
}
printf("%d\n",minc);
}
int main() {
scanf("%d%d%d",&n,&m,&K);
int i;
for(i=1;i<=n;i++) {
scanf("%d",&a[i]);
}
add(S,1,K,0); add(n-m+2,T,K,0);
for(i=1;i<=n-m+1;i++) add(i,i+1,inf,0);
for(i=1;i<=n;i++) {
if(i<=m) add(1,i+1,1,a[i]);
else if(i>n-m) add(i-m+1,n-m+2,1,a[i]);
else add(i-m+1,i+1,1,a[i]);
}
mcmf();
}

最新文章

  1. CSS教程:div垂直居中的N种方法以及多行文本垂直居中的方法
  2. java读取excel文件
  3. Android 手机卫士--构建服务端json、请求网络数据
  4. 自己存档:asp.net mvc 从filterContent得到controller和action
  5. 【leetcode】 Scramble String (hard)★
  6. PAT (Basic Level) Practise:1016. 部分A+B
  7. linux修改open files数
  8. HNOI2006-鬼谷子的钱袋
  9. MySQL使用rand函数实现随机数
  10. centos5.2 x86 安装 oracle 11g2r 日志
  11. char[]转换成wchar_t的转换方法(GNU Libc规定wchar_t为32位)
  12. 转:svn命令行操作
  13. 为什么使用bootstrap在一个页面同时做两个轮播效果时,只有第一个有效??
  14. 搜索引擎case︱从搜索序列文本看高端商务车︱统计之都
  15. 11个简单的Java性能调优技巧,傻瓜都能学会!
  16. MFC 不同窗体之间变量调用
  17. [Android Security] 如何把java代码转换成smali代码
  18. angular学习笔记(三十)-指令(3)-templateUrl
  19. python numpy 数组中元素大于等于0的元素
  20. FastAdmin 如何查看 ICON 名字?

热门文章

  1. 设计模式 - 代理模式(proxy pattern) 未使用代理模式 具体解释
  2. SpringBoot启动流程分析(二):SpringApplication的run方法
  3. Intellij IDEA如何不显示参数提示
  4. IPv4(四)子网和子网掩码
  5. implode 函数 把数组拼接成字符串
  6. 基于EasyNVR二次开发实现自己的摄像机IPC/NVR无插件化直播解决方案
  7. WCF基础之配置服务
  8. vscode设置默认shell 快速到行
  9. pgsql 数据类型
  10. Pentaho BIServer Community Edtion 6.1 使用教程 第四篇 安装和使用Saiku 插件 进行 OLAP