题目链接

最长不下降子序列问题

解题思路

分成三小问解决。

第一小问,求\(LIS\),因为\(n<=500\),直接\(O(N^2)\)暴力求解即可。

第二三小问,建立模型用网络流求解。

对于第二小问

\((1)\)首先,因为每个点只能使用一次,考虑拆点,把每一个点拆成\(i,n+i\)两个点,从\(i\)连向\(n+i\)一条长度为\(1\)的有向边。

\((2)\)其次,因为流向是从S经集合E到T,其中任意集合E中元素\(i\)需要满足的条件是\(i\)位于LIS上,故:

①出边从\(lis[i]=k\)的点流向T

②所有的能构成E的边都需要加入,也就是任意\(i,j\)满足\(i<j,a[i]<a[j],lis[i]=lis[j]-1\)都从\(i\)到\(j\)连边。

跑一遍最大流即可。

第三小问唯一的不同就是\(S\)流向\(1\),\(1\)流向\(1+n\),\(n\)流向\(n+n\),\(n+n\)流向\(T\)四条路长度变成\(inf\)而已,改后再跑一遍最大流即可。

AC代码

#include<stdio.h>
#include<string.h>
int lis[1020],a[1020],len;//lis
int s,t,inf=0x3fffffff;//ek
struct Edge{
int end,length,near;
}edge[50020];
int head[1020],cnt=2,vis[1020];
void addedge(int begin,int end,int length){
edge[cnt].end=end;
edge[cnt].length=length;
edge[cnt].near=head[begin];
head[begin]=cnt;
cnt++;
}
struct Pre{
int pre,ednum;
}pre[1020];
int bfs(){
memset(vis,0,sizeof(vis));
int queue[50010]={0},headq=0,tail=0,i;
queue[tail++]=s;
vis[s]=1;
while(headq<tail){
int v=queue[headq];
for(i=head[v];i;i=edge[i].near){
int p=edge[i].end;
if(vis[p]||!edge[i].length)continue;
vis[p]=1;
pre[p].pre=v;
pre[p].ednum=i;
queue[tail++]=p;
if(p==t)return 1;
}
headq++;
}
return 0;
}
int ek(){
int min,ans=0,i;
while(bfs()){
min=inf;
for(i=t;i!=s;i=pre[i].pre){
int en=pre[i].ednum;
if(min>edge[en].length)min=edge[en].length;
}
for(i=t;i!=s;i=pre[i].pre){
int en=pre[i].ednum;
edge[en].length-=min;
edge[en^1].length+=min;
}
ans+=min;
}
return ans;
}
int main(){
int i,j,n;
scanf("%d",&n);
s=2*n+3;
t=2*n+4;
for(i=1;i<=n;i++){
scanf("%d",&a[i]);
lis[i]=1;
}
//lis n<=500 O(N2)
for(i=1;i<=n;i++)
for(j=1;j<i;j++)
if(a[i]>=a[j]&&lis[i]<lis[j]+1)lis[i]=lis[j]+1;
for(i=1;i<=n;i++)if(lis[i]>len)len=lis[i];
printf("%d\n",len);
//ek1 建图求最大流
for(i=1;i<=n;i++){
addedge(i,i+n,1);//拆点
addedge(i+n,i,0);
if(lis[i]==1){
addedge(s,i,1);
addedge(i,s,0);
}
if(lis[i]==len){
addedge(i+n,t,1);
addedge(t,i+n,0);
}
}
for(i=1;i<=n;i++){
for(j=1;j<i;j++){
if(lis[i]==lis[j]+1&&a[i]>=a[j]){
addedge(j+n,i,1); addedge(i,j+n,0);
}
}
}
printf("%d\n",ek());
//ek2
memset(pre,0,sizeof(pre));
memset(edge,0,sizeof(edge));
memset(head,0,sizeof(head));
cnt=2;
for(i=1;i<=n;i++){
addedge(i,i+n,1);//拆点
addedge(i+n,i,0);
if(lis[i]==1){
addedge(s,i,1);
addedge(i,s,0);
}
if(lis[i]==len){
addedge(i+n,t,1);
addedge(t,i+n,0);
}
}
for(i=1;i<=n;i++){
for(j=1;j<i;j++){
if(lis[i]==lis[j]+1&&a[i]>=a[j]){
addedge(j+n,i,1); addedge(i,j+n,0);
}
}
}
addedge(1,1+n,inf); addedge(1+n,1,0);
addedge(s,1,inf); addedge(1,s,0);
if(lis[n]==len){
addedge(n,n+n,inf); addedge(n+n,n,0);
addedge(n+n,t,inf); addedge(t,n+n,0);
}
printf("%d\n",ek());
return 0;
}

P2766 最长不下降子序列问题 题解(网络流)的更多相关文章

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

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

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

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

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

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

  4. 【题解】Luogu P2766 最长不下降子序列问题

    原题传送门 实际还是比较套路的建图 先暴力dp一下反正数据很小 第一小问的答案即珂以求出数列的最长不下降子序列的长度s 考虑第二问如何做: 将每个点拆点 从前向后连一条流量为1的边 如果以它为终点的最 ...

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

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

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

    题目描述 «问题描述: 给定正整数序列x1,...,xn . (1)计算其最长不下降子序列的长度s. (2)计算从给定的序列中最多可取出多少个长度为s的不下降子序列. (3)如果允许在取出的序列中多次 ...

  7. P2766 最长不下降子序列问题

    题目描述 «问题描述: 给定正整数序列x1,...,xn . (1)计算其最长不下降子序列的长度s. (2)计算从给定的序列中最多可取出多少个长度为s的不下降子序列. (3)如果允许在取出的序列中多次 ...

  8. 洛谷P2766 最长不下降子序列问题(最大流)

    传送门 第一问直接$dp$解决,求出$len$ 然后用$f[i]$表示以$i$为结尾的最长不下降子序列长度,把每一个点拆成$A_i,B_i$两个点,然后从$A_i$向$B_i$连容量为$1$的边 然后 ...

  9. 【Luogu】P2766最长不下降子序列问题(暴力网络流)

    题目链接 水题qwq,数据都那么水. 我要是出数据的人我就卡$n^3$建图. qwq. 然而这么水的题我!居!然!没!有!1!A!!还!提!交!了!五!遍!!! md从现在开始要锻炼1A率了 看我从今 ...

随机推荐

  1. Docker配置文件deamon.json详解

    vim /etc/docker/daemon.json { "authorization-plugins": [], "data-root": "&q ...

  2. InnoDB 存储引擎简介

    InnoDB 核心特性 MVCC(Multi-Version Concurrency Control,多版本并发控制),事务处理,行级锁,热备份,自动故障恢复( Crash Safe Recovery ...

  3. Nginx 服务介绍

    目录 静态 / 动态 Web 服务 Nginx 简介 Nginx 的优点 Nginx 和 Apache 的比较 Nginx 的安装 Nginx 相关文件 Nginx 主配置文件 Nginx 虚拟主机配 ...

  4. HTTP常见状态码(200、301、302、404、500、502)详解

         概述 运维工作中,在应用部署的时候,通常遇到各种HTTP的状态码,我们比较常见的如:200.301.302.404.500.502 等,有必要整理一份常见状态码的文档,加深印象,方便回顾. ...

  5. PAT L2-016. 愿天下有情人都是失散多年的兄妹 (BFS)

    L2-016. 愿天下有情人都是失散多年的兄妹 时间限制 200 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 呵呵.大家都知道五服以内不得通婚 ...

  6. Leetcode(144)-二叉树的前序遍历

    给定一个二叉树,返回它的 前序 遍历. 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [1,2,3] 进阶: 递归算法很简单,你可以通过迭代算法完成吗? 二叉树的前序遍历有递归 ...

  7. 关于ucore实验一的资料查找

    任务:阅读实验一makefile 搞清楚ucore.img是如何构建的 $@  $<  $^  这三个变量分别是什么意思 https://blog.csdn.net/YEYUANGEN/arti ...

  8. HDU4565-数学推导求递推公式+矩阵快速幂

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4565 我们带着这个根号是没法计算的 我们仔细观察一下,(a+sqrt(b))^n用二项式定理展开,我 ...

  9. React 17 All In One

    React 17 All In One v17.0.1 https://reactjs.org/blog/2020/10/20/react-v17.html https://reactjs.org/b ...

  10. git tag All In One

    git tag All In One $ git tag --help # (cedec380)在指定的分支上打 tag $ git tag -a stable-version-1.1.1 cedec ...