题目描述

给定正整数序列 \(x_1 \sim x_n\) ,以下递增子序列均为非严格递增。

  1. 计算其最长递增子序列的长度 \(s\) 。

  2. 计算从给定的序列中最多可取出多少个长度为 \(s\) 的递增子序列。

  3. 如果允许在取出的序列中多次使用 \(x_1\) 和 \(x_n\) ,则从给定序列中最多可取出多少个长度为 \(s\) 的递增子序列。

输入格式

文件第 \(1\) 行有 \(1\) 个正整数 \(n\) ,表示给定序列的长度。接下来的 \(1\) 行有 \(n\) 个正整数 \(x_1 \sim x_n\) ​​。

输出格式

第 \(1\) 行是最长递增子序列的长度 \(s\) 。第 \(2\) 行是可取出的长度为 \(s\) 的递增子序列个数。第 \(3\) 行是允许在取出的序列中多次使用 \(x_1\) 和 \(x_n\) 时可取出的长度为 \(s\) 的递增子序列个数。

样例

样例输入

4
3 6 2 5

样例输出

2
2
3

数据范围与提示

\(1 \leq n \leq 500\)

题解

先用dp求出第一问的答案,和 \(f\) 数组,\(f[i]\) 代表以 \(i\) 为起点最长不下降子序列的长度

对于第二问,源点向 \(f[i]\) 等于第一问答案的点连边,\(f[i]=1\) 的点向汇点连边,中间的点 \(u\) 和点 \(v\) ,如果 \(f[u]=f[v]+1\) 且 \(a[u] \leq a[v]\) ,那么它们之间连边,这些边容量均为 \(1\) 。并且因为每个点只能用一次,所以拆点,中间连容量为 \(1\) 的边。跑最大流就是第二问的答案

对于第三问,把一号点和最后一个点的容量设为 \(inf\) 就好了

#include<bits/stdc++.h>
#define ui unsigned int
#define ll long long
#define db double
#define ld long double
#define ull unsigned long long
const int MAXN=1000+10,MAXM=MAXN*MAXN+10,inf=0x3f3f3f3f;
int n,a[MAXN],f[MAXN],e=1,beg[MAXN],cur[MAXN],level[MAXN],nex[MAXM<<1],to[MAXM<<1],cap[MAXM<<1],clk,vis[MAXN],s,t,ans1;
std::queue<int> q;
template<typename T> inline void read(T &x)
{T data=0,w=1;char ch=0;while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();if(ch=='-')w=-1,ch=getchar();while(ch>='0'&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar();x=data*w;
}
template<typename T> inline void write(T x,char ch='\0')
{if(x<0)putchar('-'),x=-x;if(x>9)write(x/10);putchar(x%10+'0');if(ch!='\0')putchar(ch);
}
template<typename T> inline void chkmin(T &x,T y){x=(y<x?y:x);}
template<typename T> inline void chkmax(T &x,T y){x=(y>x?y:x);}
template<typename T> inline T min(T x,T y){return x<y?x:y;}
template<typename T> inline T max(T x,T y){return x>y?x:y;}
inline void insert(int x,int y,int z)
{to[++e]=y;nex[e]=beg[x];beg[x]=e;cap[e]=z;to[++e]=x;nex[e]=beg[y];beg[y]=e;cap[e]=0;
}
inline void dp()
{for(register int i=1;i<=n;++i)f[i]=1;for(register int i=n-1;i>=1;--i)for(register int j=n;j>i;--j)if(a[j]>=a[i])chkmax(f[i],f[j]+1);for(register int i=1;i<=n;++i)chkmax(ans1,f[i]);
}
inline bool bfs()
{memset(level,0,sizeof(level));level[s]=1;q.push(s);while(!q.empty()){int x=q.front();q.pop();for(register int i=beg[x];i;i=nex[i])if(cap[i]&&!level[to[i]])level[to[i]]=level[x]+1,q.push(to[i]);}return level[t];
}
inline int dfs(int x,int maxflow)
{if(x==t||!maxflow)return maxflow;int res=0;vis[x]=clk;for(register int &i=cur[x];i;i=nex[i])if((vis[to[i]]^vis[x])&&cap[i]&&level[to[i]]==level[x]+1){int nf=dfs(to[i],min(maxflow,cap[i]));res+=nf;cap[i]-=nf;cap[i^1]+=nf;maxflow-=nf;if(!maxflow)break;}vis[x]=0;return res;
}
inline int Dinic()
{int res=0;while(bfs())clk++,memcpy(cur,beg,sizeof(cur)),res+=dfs(s,inf);return res;
}
int main()
{read(n);for(register int i=1;i<=n;++i)read(a[i]);dp();s=n+n+1,t=s+1;write(ans1,'\n');for(register int i=1;i<=n;++i){insert(i,i+n,1);if(f[i]==ans1)insert(s,i,1);if(f[i]==1)insert(i+n,t,1);for(register int j=i+1;j<=n;++j)if(a[j]>=a[i]&&f[i]==f[j]+1)insert(i+n,j,1);}write(Dinic(),'\n');if(ans1==1)write(n,'\n');else{e=0;clk=0;memset(beg,0,sizeof(beg));for(register int i=1;i<=n;++i){if(i==1||i==n){insert(i,i+n,inf);if(f[i]==ans1)insert(s,i,inf);if(f[i]==1)insert(i+n,t,inf);}else{insert(i,i+n,1);if(f[i]==ans1)insert(s,i,1);if(f[i]==1)insert(i+n,t,1);}for(register int j=i+1;j<=n;++j)if(a[j]>=a[i]&&f[i]==f[j]+1)insert(i+n,j,1);}write(Dinic(),'\n');}return 0;
}

转载于:https://www.cnblogs.com/hongyj/p/9424710.html

【刷题】LOJ 6005 「网络流 24 题」最长递增子序列相关推荐

  1. loj #6226. 「网络流 24 题」骑士共存问题

    #6226. 「网络流 24 题」骑士共存问题 题目描述 在一个 n×n\text{n} \times \text{n}n×n 个方格的国际象棋棋盘上,马(骑士)可以攻击的棋盘方格如图所示.棋盘上某些 ...

  2. loj #6004. 「网络流 24 题」圆桌聚餐(最大流)

    #6004. 「网络流 24 题」圆桌聚餐 内存限制:256 MiB时间限制:5000 ms标准输入输出 题目类型:传统评测方式:Special Judge 上传者: 匿名 提交提交记录统计讨论测试数 ...

  3. 【刷题】LOJ 6011 「网络流 24 题」运输问题

    题目描述 W 公司有 \(m\) 个仓库和 \(n\) 个零售商店.第 \(i\) 个仓库有 \(a_i\) 个单位的货物:第 \(j\) 个零售商店需要 \(b_j\) 个单位的货物.货物供需平衡, ...

  4. 【刷题】LOJ 6014 「网络流 24 题」最长 k 可重区间集

    题目描述 给定实直线 \(L\) 上 \(n\) 个开区间组成的集合 \(I\) ,和一个正整数 \(k\) ,试设计一个算法,从开区间集合 \(I\) 中选取出开区间集合 \(S \subseteq ...

  5. LOJ#6002. 「网络流 24 题」最小路径覆盖

    模板. 1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 //#include<ti ...

  6. LibreOJ #6001. 「网络流 24 题」太空飞行计划 最大权闭合图

    #6001. 「网络流 24 题」太空飞行计划 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:Special Judge 上传者: 匿名 提交提交记录统计讨论测 ...

  7. LibreOJ 6004. 「网络流 24 题」圆桌聚餐 网络流版子题

    #6004. 「网络流 24 题」圆桌聚餐 内存限制:256 MiB时间限制:5000 ms标准输入输出 题目类型:传统评测方式:Special Judge 上传者: 匿名 提交提交记录统计讨论测试数 ...

  8. 「网络流24题」 12. 软件补丁问题

    「网络流24题」 12. 软件补丁问题 状压 DP,SPFA 转移. 没错,跟网络流没任何关系. b1.b2.f1.f2 都用二进制存下来,第 i 位表示是否有这个错误. 然后从每位都是 1 到 0 ...

  9. 「网络流24题」 题目列表

    「网络流24题」 题目列表 序号 题目标题 模型 题解 1 飞行员配对方案问题 二分图最大匹配 <1> 2 太空飞行计划问题 最大权闭合子图 <2> 3 最小路径覆盖问题 二分 ...

最新文章

  1. Hyper-V 2节点集群高可用的限制
  2. IOS面试_1.浅析内存管理
  3. VTK:Points之MaskPointsFilter
  4. 创建一个QT for Android的传感器应用应用程序(摘自笔者2015年将出的《QT5权威指南》,本文为试读篇)
  5. 《Linux高性能服务器编程》学习总结(四)——TCP/IP通信案例:访问Internet上的Web服务器...
  6. Ubuntu20.04下面运行applet与freemind部署到web上(调研+找到替换方案)
  7. 20220129--CTF WEB方向刷题-- WP--非常简单的webshell题
  8. php无法创建cookie,php-curl cookie无法成功创建
  9. 《ArcGIS Runtime SDK for Android开发笔记》
  10. 计算机应用维护师实习周记,计算机系统维护专业毕业实习周记
  11. kafka-linux集群搭建小结
  12. Python之路【第八篇】:面向对象的程序设计
  13. 计算机如果添加新用户名,怎么在电脑中创建新用户
  14. 【数学建模】4 马尔萨斯人口论
  15. Linux ARM平台开发系列讲解(入门篇) 1.1.3 开发板、Ubuntu和windows三者相互连接,无需路由器,全网最详细
  16. Leave a dent in the world:陶建辉,52岁程序员与TDengine一起成长的四年
  17. 读《人件》后的一些感想
  18. java在苹果电脑上编程软件下载_KOOV编程软件mac版下载
  19. 【三】3D匹配Matching之可变形曲面匹配Deformable Surface—Based——create_deformable_surface_model()算子
  20. HTC G7 Desire制作data2sd来解决rom空间不足的问题

热门文章

  1. 快速删除大文件 多级目录 同步并删除 rsync
  2. 总结一下最近面试经常被问到的问题(2019年4月)
  3. html用ajax做三级联动,怎样使用JS+AJAX做出三级联动
  4. Ubuntu 18.04 Server必须使用netplan命令配置IP地址
  5. Markdown编辑LaTeX数学公式
  6. 开源GIS(二十)——CAD数据添加属性转GIS数据
  7. 小程序uniapp基础
  8. Java jta 原理_分布式事务JTA实现Atomikos与Spring集成实践
  9. android recyclerview多布局_图文讲解RecyclerView的复用机制 ||Recyclerview进阶
  10. oracle中dual最多存多大_ORACLE中dual用法详解