传送门

第一问直接$dp$解决,求出$len$

然后用$f[i]$表示以$i$为结尾的最长不下降子序列长度,把每一个点拆成$A_i,B_i$两个点,然后从$A_i$向$B_i$连容量为$1$的边

然后考虑$f[i]$,如果$f[i]==1$,则从$s$向$A_i$连边,如果$f[i]==len$,那么从$B_i$向$t$连边

然后将每一个$j<i,f[j]+1==f[i],a[j]\leq a[i]$的$j$向$i$连边

以上容量全为$1$

建完图之后跑一个最大流

这样可以保证分层图里选出来的不下降子序列长度必为$len$

然后第三问的话,就把关于$1$和$n$的容量限制给取消掉就好了,就是$s$向$A_1$连$inf$,$A_1$向$B_1$连$inf$,$A_n$向$B_n$连$inf$,$B_n$向$t$连$inf$(如果$f[n]!=len$就不用连了)

然后再跑一次最大流就是第三问的答案

 //minamoto
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define inf 0x3f3f3f3f
using namespace std;
#define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[<<],*p1=buf,*p2=buf;
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,:;}
inline int read(){
#define num ch-'0'
char ch;bool flag=;int res;
while(!isdigit(ch=getc()))
(ch=='-')&&(flag=true);
for(res=num;isdigit(ch=getc());res=res*+num);
(flag)&&(res=-res);
#undef num
return res;
}
const int N=,M=;
int ver[M],Next[M],head[N],edge[M],cur[N],dep[N],tot=,a[N],dp[N];
int n,m,s,t,ans,len=;
queue<int> q;
inline void add(int u,int v,int e){
ver[++tot]=v,Next[tot]=head[u],head[u]=tot,edge[tot]=e;
ver[++tot]=u,Next[tot]=head[v],head[v]=tot,edge[tot]=;
}
bool bfs(){
memset(dep,-,sizeof(dep));
while(!q.empty()) q.pop();
for(int i=;i<=*n+;++i) cur[i]=head[i];
q.push(s),dep[s]=;
while(!q.empty()){
int u=q.front();q.pop();
for(int i=head[u];i;i=Next[i]){
int v=ver[i];
if(dep[v]<&&edge[i]){
dep[v]=dep[u]+,q.push(v);
if(v==t) return true;
}
}
}
return false;
}
int dfs(int u,int limit){
if(!limit||u==t) return limit;
int flow=,f;
for(int i=head[u];i;i=Next[i]){
int v=ver[i];
if(dep[v]==dep[u]+&&(f=dfs(v,min(limit,edge[i])))){
flow+=f,limit-=f;
edge[i]-=f,edge[i^]+=f;
if(!limit) break;
}
}
return flow;
}
void dinic(){
while(bfs()) ans+=dfs(s,inf);
}
int main(){
n=read();
for(int i=;i<=n;++i) a[i]=read(),dp[i]=;
for(int i=;i<=n;++i){
for(int j=;j<i;++j)
if(a[j]<=a[i]) cmax(dp[i],dp[j]+);
cmax(len,dp[i]);
}
printf("%d\n",len);
s=,t=*n+;
for(int i=;i<=n;++i){
if(dp[i]==) add(s,i,);
if(dp[i]==len) add(i+n,t,);
add(i,i+n,);
}
for(int i=;i<=n;++i)
for(int j=;j<i;++j)
if(a[j]<=a[i]&&dp[j]==dp[i]-) add(j+n,i,);
dinic();printf("%d\n",ans);
add(,n+,inf),add(s,,inf);
if(dp[n]==len) add(n,n<<,inf),add(n<<,t,inf);
dinic();printf("%d\n",ans);
return ;
}

洛谷P2766 最长不下降子序列问题(最大流)的更多相关文章

  1. 洛谷 P2766 最长不下降子序列问【dp+最大流】

    死于开小数组的WA?! 第一问n方dp瞎搞一下就成,f[i]记录以i结尾的最长不下降子序列.记答案为mx 第二问网络流,拆点限制流量,s向所有f[i]为1的点建(s,i,1),所有f[i]为mx(i+ ...

  2. 洛谷 [P2766] 最长不下降子序列问题

    啊啊啊,再把MAXN和MAXM搞反我就退役 层次图求不相交路径数 第一问简单DP 第二问想办法把每一个不上升子序列转化成DAG上的一条路径,就转换成了求不相交路径数 因为每一个数只能用一次,所以要拆点 ...

  3. 洛谷P2766 最长不下降子序列问题 网络流_DP

    Code: #include<cstdio> #include<iostream> #include<vector> #include<algorithm&g ...

  4. 洛谷.T22136.最长不下降子序列(01归并排序 分治)

    题目链接 \(Description\) 给定一个长为n的序列,每次可以反转 \([l,r]\) 区间,代价为 \(r-l+1\).要求在\(4*10^6\)代价内使其LIS长度最长,并输出需要操作的 ...

  5. 【24题】P2766最长不下降子序列问题

    网络流二十四题 网络流是个好东西,希望我也会. 网络流?\(orz\ zsy!!!!!\) P2766 最长不下降子序列问题 考虑我们是如何\(dp\)这个\(LIS\)的. 我们是倒着推,设置\(d ...

  6. [**P2766** 最长不下降子序列问题](https://www.luogu.org/problemnew/show/P2766)

    P2766 最长不下降子序列问题 考虑我们是如何\(dp\)这个\(LIS\)的. 我们是倒着推,设置\(dp(i)\)代表以\(i\)为起点的\(LIS\)是多少.转移太显然了 \[ dp(i)=m ...

  7. P2766 最长不下降子序列问题 网络流重温

    P2766 最长不下降子序列问题 这个题目还是比较简单的,第一问就是LIS 第二问和第三问都是网络流. 第二问要怎么用网络流写呢,首先,每一个只能用一次,所以要拆点. 其次,我们求的是长度为s的不下降 ...

  8. 洛谷P2766 最长递增子序列问题

    https://www.luogu.org/problemnew/show/P2766 注:题目描述有误,本题求的是最长不下降子序列 方案无限多时输出 n 网络流求方案数,长见识了 第一问: DP 同 ...

  9. P2766 最长不下降子序列问题 网络流

    link:https://www.luogu.org/problemnew/show/P2766 题意 给定正整数序列x1,...,xn . (1)计算其最长不下降子序列的长度s. (2)计算从给定的 ...

随机推荐

  1. 优化深度神经网络(三)Batch Normalization

    Coursera吴恩达<优化深度神经网络>课程笔记(3)-- 超参数调试.Batch正则化和编程框架 1. Tuning Process 深度神经网络需要调试的超参数(Hyperparam ...

  2. Android 4 学习(12):Linkify & Broadcast event

    参考<Professional Android 4 Development> Linkify Linkfy类可以在Text View中创建超链接.匹配LInkify中正则表达式的文本将被L ...

  3. Java面向对象-面向对象编程之基本概念

    面向对象这个概念,每本书上的说法定义很多. 我自己根据我的经验,自己归档总结了下, 所谓面向对象,就是 以基于对象的思维去分析和解决问题,万物皆对象: 面向对象经常和面向过程放一起讨论: 这里举例, ...

  4. 一.volatile关键字

    一.volatile关键字的原理 使用volatile关键字增加了实例变量在多个线程之间的可见性.但volatile的最致命的缺点是不支持原子性. synchronized代码块具有volatile同 ...

  5. 「小程序JAVA实战」微信开发者工具helloworld(三)

    转自:https://idig8.com/2018/08/09/xiaochengxu-chuji-03/ 第一个小程序demo的运行,首选需要去使用开发工具 开发工具下载安装 https://mp. ...

  6. 微信公众平台PHP示例一

    <?php /** * Created by PhpStorm. * User: Administrator * Date: 2015-12-18 * Time: 21:51 */ define ...

  7. zookpeer的安装与配置

    zookpeer集群搭建: 集群搭建过程简介: 这里准3台服务器做zk(zookpeer下面简称zk)集群搭建: zk集群由一个leader和两个follower组成,对外端口默认为2181端口,关于 ...

  8. Clean小程序(控件消息)

    一 . 准备工作 创建一个基于对话框的MFC项目 删除对话框上的工具 二 . 实现将seven图片贴到上面,按一下则换一张图片 1.在资源视图中添加位图资源,通过属性修改图片ID 2.将对话框拉长,防 ...

  9. jar包上传到jcenter

    H:\[BOOT]\gradle-5.0-bin\gradle-5.0\gradle.properties # in $HOME/.gradle/gradle.properties java6Home ...

  10. Elasticsearch聚合限制内存使用

    限制内存使用 通常为了让聚合(或者任何需要访问字段值的请求)能够快点,访问fielddata一定会快点, 这就是为什么加载到内存的原因.但是加载太多的数据到内存会导致垃圾回收(gc)缓慢, 因为JVM ...