P2766 [网络流24题]最长不下降子序列问题
«问题描述:
给定正整数序列$x_1,...,x_n$ 。$n<=500$
求(1)计算其最长不下降子序列的长度$s$。
(2)计算从给定的序列中最多可取出多少个长度为$s$的不下降子序列。
(3)如果允许在取出的序列中多次使用$x_1$和$x_n$,则从给定序列中最多可取出多少个长度为$s$的不下降子序列。
(1)暴力n方解决
(2)建分层图,把图每个顶点i按照F[i]的不同分为若干层,这样图中从S出发到T的任何一条路径都是一个满足条件的最长不下降子序列。由 S 向所有$ f_i = 1$ 的$ i $连容量为$ 1 $的边,由 所有$ f_i = s $的$ i $向$ T $连容量为$ 1$ 的边。对于所有的$ (i,j)$,若$ i < j,f_i +1 = f_j$,则由$ i$ 向$ j$ 连容量为 $1$ 的边。这样一来,所 有从 $S$ 出发到达$ T$ 的的路径都是一个长度为 $s $的上升子序 列。
注意拆点,以保证同一个数不会重复使用。一个连入边,一个连出边,两个点 之间连流量为 1 的限制边。
注意事项: line49的条件判断注意$f[j]+1==f[i]$的前提是要$a[j]<=a[i]$才可以连边!
(3)把之前的边的流量限制改一下即可,对1号和n号微调后原样跑。
注意事项(其实网上绝大部分题解好像都忽略了):建边时s向1号点的容量不可为无穷,应设为n, n号点连t同理.
比如这个毒瘤数据
1
1
绝大部分题解输的是INF,但其实是1
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
template<typename T>inline char MIN(T&A,T B){return A>B?A=B,:;}
template<typename T>inline char MAX(T&A,T B){return A<B?A=B,:;}
template<typename T>inline T _min(T A,T B){return A<B?A:B;}
template<typename T>inline T _max(T A,T B){return A>B?A:B;}
template<typename T>inline T read(T&x){
x=;char c;while(!isdigit(c=getchar()))if(isalpha(c))return x=(int)c;
while(isdigit(c))x=(x<<)+(x<<)+(c^),c=getchar();return x;
}
const int N=+,M=+,INF=0x3f3f3f3f;
int w[][M<<],v[][M<<],Next[][M<<],Head[][N<<],cur[][N<<],dis[][N<<],tot[],s,t,n;
inline void Addedge(int x,int y,int z,int p){
v[p][++tot[p]]=y,Next[p][tot[p]]=Head[p][x],Head[p][x]=tot[p],w[p][tot[p]]=z;
v[p][++tot[p]]=x,Next[p][tot[p]]=Head[p][y],Head[p][y]=tot[p],w[p][tot[p]]=;
}
#define y v[p][j]
inline char bfs(int p){
queue<int> q;q.push(s),memset(dis[p],,sizeof dis[p]),dis[p][s]=;
for(register int i=;i<=(n<<)+;++i)cur[p][i]=Head[p][i];
while(!q.empty()){
int x=q.front();q.pop();
for(register int j=Head[p][x];j;j=Next[p][j])if(w[p][j]&&!dis[p][y]){
dis[p][y]=dis[p][x]+,q.push(y);
if(y==t)return ;
}
}
return ;
}
int dinic(int x,int flow,int p){
if(!flow||x==t)return flow;
int rest=flow,k;
for(register int j=cur[p][x];j&&rest;cur[p][x]=j,j=Next[p][j])if(w[p][j]&&dis[p][y]==dis[p][x]+){
if(!(k=dinic(y,_min(rest,w[p][j]),p)))dis[p][y]=;
rest-=k,w[p][j]-=k,w[p][j^]+=k;
}
return flow-rest;
}
#undef y
int a[N],f[N],ans,maxflow; int main(){//freopen("P2766.in","r",stdin);//freopen("P2766.txt","w",stdout);
read(n);s=(n<<)+,t=s+,tot[]=tot[]=;
for(register int i=;i<=n;++i){
read(a[i]);f[i]=;
for(register int j=;j<i;++j)if(a[j]<=a[i])MAX(f[i],f[j]+);
for(register int j=;j<i;++j)if(f[j]+==f[i]&&a[j]<=a[i])Addedge(j+n,i,,),Addedge(j+n,i,,);
MAX(ans,f[i]),Addedge(i,i+n,,);if(f[i]==)Addedge(s,i,,),i==?Addedge(s,i,n,):Addedge(s,i,,);
if(i==||i==n)Addedge(i,i+n,n,);else Addedge(i,i+n,,);
}
printf("%d\n",ans);
for(register int i=;i<=n;++i)if(f[i]==ans)Addedge(i+n,t,,),i==n?Addedge(i+n,t,n,):Addedge(i+n,t,,);
while(bfs())maxflow+=dinic(s,n,);
printf("%d\n",maxflow);maxflow=;
while(bfs())maxflow+=dinic(s,n,);
printf("%d\n",maxflow);
return ;
}
P2766 [网络流24题]最长不下降子序列问题的更多相关文章
- Cogs 731. [网络流24题] 最长递增子序列(最大流)
[网络流24题] 最长递增子序列 ★★★☆ 输入文件:alis.in 输出文件:alis.out 简单对比 时间限制:1 s 内存限制:128 MB «问题描述: 给定正整数序列x1,-, xn. ( ...
- COGS743. [网络流24题] 最长k可重区间集
743. [网络流24题] 最长k可重区间集 ★★★ 输入文件:interv.in 输出文件:interv.out 简单对比时间限制:1 s 内存限制:128 MB «问题描述: «编 ...
- [网络流24题]最长k可重区间集[题解]
最长 \(k\) 可重区间集 题目大意 给定实心直线 \(L\) 上 \(n\) 个开区间组成的集合 \(I\) ,和一个正整数 \(k\) ,试设计一个算法,从开区间集合 \(I\) 中选取开区间集 ...
- [网络流24题] 最长K可重区间集问题
题目链接:戳我 当时刷24题的时候偷了懒,没有写完,结果落下这道题没有写qwq结果今天考试T3中就有一部分要用到这个思想,蒟蒻我硬是没有想到网络流呜呜呜 最大费用流. 就是我们考虑将问题转化一下,转化 ...
- COGS731 [网络流24题] 最长递增子序列(最大流)
给定正整数序列x1,..., xn (n<=500).(1)计算其最长递增子序列的长度s.(2)计算从给定的序列中最多可取出多少个长度为s的递增子序列.(3)如果允许在取出的序列中多次使用x1和 ...
- 网络流24题-最长k可重线段集问题
最长k可重线段集问题 时空限制1000ms / 128MB 题目描述 给定平面 x−O−y 上 n 个开线段组成的集合 I,和一个正整数 k .试设计一个算法,从开线段集合 I 中选取出开线段集合 S ...
- [网络流24题] 最长k可重区间集问题 (费用流)
洛谷传送门 LOJ传送门 很巧妙的建图啊...刚了$1h$也没想出来,最后看的题解 发现这道题并不类似于我们平时做的网络流题,它是在序列上的,且很难建出来二分图的形. 那就让它在序列上待着吧= = 对 ...
- [网络流24题]最长k可重线段集[题解]
最长 \(k\) 可重线段集 题目大意 给定平面 \(x-O-y\) 上 \(n\) 个开线段组成的集合 \(I\) ,和一个正整数 \(k\) .试设计一个算法,从开线段集合 \(I\) 中选取开线 ...
- [网络流24题] 最长k可重区间集
https://www.luogu.org/problemnew/show/3358 以区间(1,5),(2,6),(7,8)为例 建模方法一: 建模方法二: 离散化区间端点 相当于找k条费用最大的不 ...
随机推荐
- js将字符串转变成数字
方法主要有三种 转换函数.强制类型转换.利用js变量弱类型转换. 1. 转换函数: js提供了parseInt()和parseFloat()两个转换函数.前者把值转换成整数,后者把值转换成浮点数.只有 ...
- uboot之run_command简单分析
本文档简单分析了uboot中命令的实现.run_command函数的实现以及从uboot命令行接收并处理命令的过程. 作者: 彭东林 邮箱: pengdonglin137@163.com http:/ ...
- 【selenium+Python unittest】之发送带中文附件的邮箱
完整原码如下: import smtplib from email.mime.text import MIMEText #from email.header import Header from em ...
- Svn服务器备份迁移小结
注:svn备份千万不要采用打包压缩,然后解压文件的方式. 备份和还原之前先要关掉svn服务器. svn备份一般采用三种方式: 1)svnadmin dump 2)svnadmin hotcopy 3) ...
- Python 时间格式化(转)
From:http://www.cnblogs.com/65702708/archive/2011/04/17/2018936.html http://www.wklken.me/posts/2015 ...
- ssh无密码登陆屌丝指南
[0]写在前面 由于ssh 实现的是免密码登陆,大致步骤是: 0.1) client通过ssh登陆到server: 0.2) server检查家目录下的.ssh文件, 并发送公钥文件 authoriz ...
- Eclipse中执行Tomcat源代码
1. 到http://archive.apache.org/dist/tomcat/tomcat-7下载Tomcat源码,本文用到的是apache-tomcat-7.0.19-src.zip: 注意: ...
- RedHat7 防火墙设置以及端口设置
1.查看防火墙状态,root用户登录,执行命令systemctl status firewalld 2.开启防火墙:systemctl start firewalld 3.关闭防火墙:systemct ...
- 小程序的生命周期 launchApp
https://developers.weixin.qq.com/miniprogram/dev/api/launchApp.html?search-key=生命周期 launchApp(OBJECT ...
- Swift语言概览
Swift语言概览 关于 这篇文章简要介绍了苹果于WWDC 2014公布的编程语言--Swift. 前言 在这里我觉得有必要提一下Brec Victor的Invent ...