原题传送门

实际还是比较套路的建图

先暴力dp一下反正数据很小

第一小问的答案即珂以求出数列的最长不下降子序列的长度s

考虑第二问如何做:

将每个点拆点

从前向后连一条流量为1的边

如果以它为终点的最长不下降子序列长度为1,从源点向它(前)连一条流量为1的边

如果以它为终点的最长不下降子序列长度为s,从它(后)向汇点连一条流量为1的边

如果一个点为终点的最长不下降子序列长度加一等于以它后面一个点为终点最长不下降子序列长度且(注意:是而且)前者的数值小于等于后者的数值,珂以从前者(后)向后者(前)连一条流量为1的边

跑一下ISAP就的出子任务2的答案

第三个子问题很简单,只需再稍加改进

从源点向1号点(前)连一条流量为inf的边,从1号点前面向后连一条流量为inf的边

当以n号点为终点的最长不下降子序列长度为s,从n号点(后)向汇点连一条流量为inf的边,从n号点前面向后连一条流量为inf的边

在跑一边ISAP就能求出子问题3的答案

注意:子任务3最大流算出来的答案要加上子任务2的答案(做子任务3时ISAP跑的图已经是残量网络了)

#include <bits/stdc++.h>
#define N 505
#define M 50005
#define inf 0x7f7f7f7f
#define getchar nc
using namespace std;
inline char nc(){
static char buf[100000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline int read()
{
register int x=0,f=1;register char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return x*f;
}
inline void write(register int x)
{
if(!x)putchar('0');if(x<0)x=-x,putchar('-');
static int sta[20];register int tot=0;
while(x)sta[tot++]=x%10,x/=10;
while(tot)putchar(sta[--tot]+48);
}
inline int Max(register int a,register int b)
{
return a>b?a:b;
}
inline int Min(register int a,register int b)
{
return a<b?a:b;
}
struct node{
int to,nxt,v;
}e[M];
int head[N<<1],cnt=1;
inline void add(register int u,register int v,register int val)
{
e[++cnt]=(node){v,head[u],val};
head[u]=cnt;
}
int n,a[N],f[N],len=0,s,t,nn;
int dep[N<<1],gap[N<<1],cur[N<<1],maxflow;
inline void bfs()
{
memset(dep,-1,sizeof(dep));
memset(gap,0,sizeof(gap));
dep[t]=0;
++gap[dep[t]];
queue<int> q;
q.push(t);
while(!q.empty())
{
int u=q.front();
q.pop();
for(register int i=head[u];i;i=e[i].nxt)
{
int v=e[i].to;
if(dep[v]!=-1)
continue;
q.push(v);
dep[v]=dep[u]+1;
++gap[dep[v]];
}
}
}
inline int dfs(register int u,register int flow)
{
if(u==t)
{
maxflow+=flow;
return flow;
}
int used=0;
for(register int i=cur[u];i;i=e[i].nxt)
{
cur[u]=i;
int v=e[i].to;
if(e[i].v&&dep[v]+1==dep[u])
{
int tmp=dfs(v,Min(e[i].v,flow-used));
if(tmp)
{
e[i].v-=tmp;
e[i^1].v+=tmp;
used+=tmp;
}
if(used==flow)
return used;
}
}
--gap[dep[u]++]==0?dep[s]=nn+1:++gap[dep[u]];
return used;
}
inline void ISAP()
{
bfs();
while(dep[s]<nn)
{
memcpy(cur,head,sizeof(head));
dfs(s,inf);
}
}
int main()
{
n=read();
for(register int i=1;i<=n;++i)
{
a[i]=read(),f[i]=1;
for(register int j=1;j<i;++j)
if(a[j]<=a[i])
f[i]=Max(f[i],f[j]+1);
len=Max(len,f[i]);
}
write(len),puts("");
s=0,t=(n<<1)+1;
for(register int i=1;i<=n;++i)
{
add(i,i+n,1),add(i+n,i,0);
if(f[i]==1)
add(s,i,1),add(i,s,0);
if(f[i]==len)
add(i+n,t,1),add(t,i+n,0);
}
for(register int i=1;i<n;++i)
for(register int j=i+1;j<=n;++j)
if(a[i]<=a[j]&&f[i]+1==f[j])
add(i+n,j,1),add(j,i+n,0);
nn=(n<<1)+2,maxflow=0;
ISAP();
write(maxflow),puts("");
add(1,1+n,inf),add(1+n,1,0);
add(s,1,inf),add(1,s,0);
if(f[n]==len)
{
add(n,n<<1,inf),add(n<<1,n,0);
add(n<<1,t,inf),add(t,n<<1,0);
}
ISAP();
write(maxflow);
return 0;
}

【题解】Luogu P2766 最长不下降子序列问题的更多相关文章

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

    第一问可以直接DP来做,联想上一题,线性规划都可以化为网络流?我们可以借助第一问的DP数组,来建立第二问第三问的网络流图,考虑每一种可能,都是dp数组中满足num[i]>=num[j]& ...

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

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

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

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

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

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

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

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

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

    题目链接 最长不下降子序列问题 解题思路 分成三小问解决. 第一小问,求\(LIS\),因为\(n<=500\),直接\(O(N^2)\)暴力求解即可. 第二三小问,建立模型用网络流求解. 对于 ...

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

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

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

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

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

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

随机推荐

  1. hibernate源码分析1

  2. git 处理

    [添加]cd 路径(进入文件夹) git clone url git status (查看状态) cd firstprojected 进入这个文件夹 查看 git status 有 index.php ...

  3. IkAnalyzer2012FF_u1.jar免费下载

    链接:https://pan.baidu.com/s/1P_0cdRLKJO4VIUTokvTS0g 提取码:qt3w

  4. jq 点击按钮显示div,点击页面其他任何地方隐藏div

    css .bl_rencai_32{ float: left; height: 35px; line-height: 35px; } .bl_rencai_32 >input{ width: 3 ...

  5. php(面向对象的基本介绍)

    面向对象思想介绍 OOP:Object Oriented Program面向对象编程. 面向对象三大特性 封装   继承   多态 类与对象 类:是用于描述“某一些具有共同特征”的物体的概念,是某一类 ...

  6. div加链接 html给div加超链接实现点击div跳转的方法[申明:来源于网络]

    div加链接 html给div加超链接实现点击div跳转的方法[申明:来源于网络] 地址:http://www.cdxwcx.com/faq/htmldivLink.html

  7. P1_jemeter安装--jdk安装

    学习的python,需要下载jemter做接口测试. 一..jMeter介绍 Apache组织开发的基于JAVA压力测试工具 100%纯JAVA开发,完全可移植性 可用于测试静态和动态资源 多协议-- ...

  8. SQL基础语法提纲

    一.SQL需知5点 1.SQL是Structured Query Language的缩写,是用来访问关系型数据库的,非过程化的,高级编程语言. 2.SQL具有语法高度综合统一,高度的非过程化,对集合进 ...

  9. poi导入excel表格数据到数据库的时候,对出生日期的校验

    出生日期格式为8位数字的字符串 如:yyyyMMdd 规则:yyyy大于1900并小于当前时间,月.日 按日期规则校验 //解决读过来的字符串显示为科学计数法问题 BigDecimal bd = ne ...

  10. ts-loader 安装问题

    首先,有个问题:ts-loader是将typescript转成javascript,转成哪个版本的javascript版本? 查询到参考地址:http://morning.work/page/othe ...