ha~

«问题描述:

给定正整数序列$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题]最长不下降子序列问题的更多相关文章

  1. Cogs 731. [网络流24题] 最长递增子序列(最大流)

    [网络流24题] 最长递增子序列 ★★★☆ 输入文件:alis.in 输出文件:alis.out 简单对比 时间限制:1 s 内存限制:128 MB «问题描述: 给定正整数序列x1,-, xn. ( ...

  2. COGS743. [网络流24题] 最长k可重区间集

    743. [网络流24题] 最长k可重区间集 ★★★   输入文件:interv.in   输出文件:interv.out   简单对比时间限制:1 s   内存限制:128 MB «问题描述: «编 ...

  3. [网络流24题]最长k可重区间集[题解]

    最长 \(k\) 可重区间集 题目大意 给定实心直线 \(L\) 上 \(n\) 个开区间组成的集合 \(I\) ,和一个正整数 \(k\) ,试设计一个算法,从开区间集合 \(I\) 中选取开区间集 ...

  4. [网络流24题] 最长K可重区间集问题

    题目链接:戳我 当时刷24题的时候偷了懒,没有写完,结果落下这道题没有写qwq结果今天考试T3中就有一部分要用到这个思想,蒟蒻我硬是没有想到网络流呜呜呜 最大费用流. 就是我们考虑将问题转化一下,转化 ...

  5. COGS731 [网络流24题] 最长递增子序列(最大流)

    给定正整数序列x1,..., xn (n<=500).(1)计算其最长递增子序列的长度s.(2)计算从给定的序列中最多可取出多少个长度为s的递增子序列.(3)如果允许在取出的序列中多次使用x1和 ...

  6. 网络流24题-最长k可重线段集问题

    最长k可重线段集问题 时空限制1000ms / 128MB 题目描述 给定平面 x−O−y 上 n 个开线段组成的集合 I,和一个正整数 k .试设计一个算法,从开线段集合 I 中选取出开线段集合 S ...

  7. [网络流24题] 最长k可重区间集问题 (费用流)

    洛谷传送门 LOJ传送门 很巧妙的建图啊...刚了$1h$也没想出来,最后看的题解 发现这道题并不类似于我们平时做的网络流题,它是在序列上的,且很难建出来二分图的形. 那就让它在序列上待着吧= = 对 ...

  8. [网络流24题]最长k可重线段集[题解]

    最长 \(k\) 可重线段集 题目大意 给定平面 \(x-O-y\) 上 \(n\) 个开线段组成的集合 \(I\) ,和一个正整数 \(k\) .试设计一个算法,从开线段集合 \(I\) 中选取开线 ...

  9. [网络流24题] 最长k可重区间集

    https://www.luogu.org/problemnew/show/3358 以区间(1,5),(2,6),(7,8)为例 建模方法一: 建模方法二: 离散化区间端点 相当于找k条费用最大的不 ...

随机推荐

  1. Autoprefixer:一个以最好的方式处理浏览器前缀的后处理程序

    Autoprefixer解析CSS文件并且添加浏览器前缀到CSS规则里,使用Can I Use的数据来决定哪些前缀是需要的. 所有你需要做的就是把它添加到你的资源构建工具(例如 Grunt)并且可以完 ...

  2. 畅通project再续 HDU杭电1875 【Kruscal算法 || Prim】

    Problem Description 相信大家都听说一个"百岛湖"的地方吧.百岛湖的居民生活在不同的小岛中.当他们想去其它的小岛时都要通过划小船来实现.如今政府决定大力发展百岛湖 ...

  3. UIWebView使用中的内存相关问题

    本文转载至: http://blog.csdn.net/musou_ldns/article/details/7675589   applicationios5webkit测试cacheios 在iO ...

  4. 【BZOJ4240】有趣的家庭菜园 树状数组+贪心

    [BZOJ4240]有趣的家庭菜园 Description 对家庭菜园有兴趣的JOI君每年在自家的田地中种植一种叫做IOI草的植物.JOI君的田地沿东西方向被划分为N个区域,由西到东标号为1~N.IO ...

  5. 使用EasyPusher进行手机低延时直播推流便捷开发

    基于EasyPusher sdk库工程(即library module)实现一个推送客户端非常简单便捷,因为sdk端已经将各种烦人的状态维护\错误检查\权限判定\UI同步等功能都实现了,开发者仅仅只需 ...

  6. python中的raw字符串

    在正则表达式的字符串前面加上r表示这个是一个raw字符串,只以正则表达式的元字符进行解析,不用理会ascii的特殊字符.

  7. git查看某一次commit里面的内容,即本次commit相对于原来的版本进行了哪些修改

    1 知道commit id的话 git show commit-id 2 想要查看某次commit的某个文件进行了哪些修改 git show commit-id filename

  8. Linux搭建FTP服务器实战

    首先准备一台Linux系统机器(虚拟机也可), 检测出是否安装了vsftpd软件: rpm -qa |grep vsftpd 如果没有输出结果,就是没有安装. 使用命令安装,安装过程中会有提示,直接输 ...

  9. hadoop磁盘空间不均衡的解决办法

    hadoop集群在运行一段时间后,总是会出现某台机器的磁盘使用率特别高,有的使用率特别低,针对这种情况,hadoop提供了balancer工具调整磁盘负载 使用命令:start-balancer.sh ...

  10. 模拟登陆,selenium,线程池

    一 . 模拟登陆案例(识别验证码)  1 . 打码平台 - 云打码 : www.yundama.com  使用步骤 : - 注册两个账户,普通用户和开发者用户 : - 登陆 普通用户查看余额 登陆开发 ...