Libre 6005 「网络流 24 题」最长递增子序列 / Luogu 2766 最长递增子序列问题(网络流,最大流)
Libre 6005 「网络流 24 题」最长递增子序列 / Luogu 2766 最长递增子序列问题(网络流,最大流)
Description
问题描述:
给定正整数序列x1,...,xn 。
(1)计算其最长递增子序列的长度s。
(2)计算从给定的序列中最多可取出多少个长度为s的递增子序列。
(3)如果允许在取出的序列中多次使用x1和xn,则从给定序列中最多可取出多少个长度为s的递增子序列。
编程任务:
设计有效算法完成(1)(2)(3)提出的计算任务。
Input
第1 行有1个正整数n,表示给定序列的长度。接下来的1 行有n个正整数n:x1, ..., xn。
Output
第1 行是最长递增子序列的长度s。第2行是可取出的长度为s 的递增子序列个数。第3行是允许在取出的序列中多次使用x1和xn时可取出的长度为s 的递增子序列个数。
Sample Input
4
3 6 2 5
Sample Output
2
2
3
Http
Libre:https://loj.ac/problem/6005
Luogu:https://www.luogu.org/problem/show?pid=2766
Source
网络流,最大流
解决思路
看清题目,不是最长递增子序列是最长不下降子序列。
这道题目首先运用动态规划的方式求出最长不下降子序列,这也是第一问的内容。注意,本题不能使用单调队列的方式,因为要求出到每一个数的最长不下降子序列长度(后面记为F),这在后两问中要用。
那么如何求解第二问呢?
我们把每一个数拆成两个点入点和出点,在每一个数的入点和出点之间连容量为1的边,同时设置一个源点一个汇点。从前往后扫描每一个数,若发现第i个数的F[i]最长不下降子序列长度,则在源点与i的出点之间连一条容量为1的边。若F[i]1,则在其出点与汇点之间连一条容量为1的边。并且,对于任何数i,扫描其前面的每一个数j,若F[i]==F[j]+1且第j位的数<=第i位的数,则在i的出点与j的入点之间连一条容量为1的边。
这样建图,有点类似于分层图的思想,从最高层的F为最长不下降子序列长度,往下每一层长度减一,直到最底下一层长度为1。这样我们跑一边最短路就可以了。
至于第三问,我们只要在重新建图的时候把1到汇点,1的入点到出点,n的入点到出点,源点到n(如果存在的话)这几条边设置为无穷大即可。
但要注意,第三问要特判一下递减的情况,因为这样最长不下降子序列长度为1,跑最大流会出现无穷大的流的情况。
另:这里用Dinic求解最大流,具体请移步我的这篇文章
代码
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxN=2000;
const int maxM=maxN*maxN*4;
const int inf=147483647;
class Edge
{
public:
int u,v,flow;
};
int n;
int cnt=-1;
int F[maxN];
int Arr[maxN];
int Head[maxN];
int Next[maxM];
Edge E[maxM];
int depth[maxN];
int cur[maxN];
int Q[maxM];
void Add_Edge(int u,int v,int flow);
bool bfs();
int dfs(int u,int flow);
int main()
{
scanf("%d",&n);
for (int i=1;i<=n;i++)
scanf("%d",&Arr[i]);
for (int i=1;i<=n;i++)//动态规划求出最长不下降子序列
{
F[i]=1;
for (int j=1;j<i;j++)
if (Arr[j]<=Arr[i])
F[i]=max(F[i],F[j]+1);
}
int maxlength=1;
for (int i=1;i<=n;i++)
maxlength=max(maxlength,F[i]);//得出第一问答案
printf("%d\n",maxlength);
memset(Head,-1,sizeof(Head));
for (int i=1;i<=n;i++)//构造第二问的图
{
Add_Edge(i,i+n,1)//连接入点和出点
if (F[i]==maxlength)//若与最长长度相同,则连接源点
Add_Edge(0,i,1);
if (F[i]==1)//若为最小长度1,则连接汇点
Add_Edge(i+n,n*2+1,1);
for (int j=1;j<i;j++)
if ((F[j]==F[i]-1)&&(Arr[j]<=Arr[i]))//向前统计能连的
Add_Edge(i+n,j,1);
}
int Ans=0;//求解最大流
while (bfs())
{
for (int i=0;i<=2*n+1;i++)
cur[i]=Head[i];
while (int di=dfs(0,inf))
Ans+=di;
}
cout<<Ans<<endl;
memset(Head,-1,sizeof(Head));
cnt=-1;
for (int i=1;i<=n;i++)//构造第三问的图
{
int nowflow=1;
if ((i==1)||(i==n))//1和n的流量为无穷大
nowflow=inf;
if (maxlength==1)//注意这里特判递减序列的情况
Add_Edge(i,i+n,1);
else
Add_Edge(i,i+n,inf);
if (F[i]==maxlength)
Add_Edge(0,i,nowflow);
if (F[i]==1)
Add_Edge(i+n,n*2+1,nowflow);
for (int j=1;j<i;j++)
if ((F[j]==F[i]-1)&&(Arr[j]<=Arr[i]))
Add_Edge(i+n,j,1);
}
Ans=0;//求解最大流
while (bfs())
{
for (int i=0;i<=2*n+1;i++)
cur[i]=Head[i];
while (int di=dfs(0,inf))
Ans+=di;
}
cout<<Ans<<endl;
return 0;
}
void Add_Edge(int u,int v,int flow)
{
cnt++;
Next[cnt]=Head[u];
Head[u]=cnt;
E[cnt].u=u;
E[cnt].v=v;
E[cnt].flow=flow;
cnt++;
Next[cnt]=Head[v];
Head[v]=cnt;
E[cnt].v=u;
E[cnt].u=v;
E[cnt].flow=0;
}
bool bfs()
{
memset(depth,-1,sizeof(depth));
int h=1,t=0;
Q[1]=0;
depth[0]=1;
do
{
t++;
int u=Q[t];
//cout<<u<<endl;
for (int i=Head[u];i!=-1;i=Next[i])
{
int v=E[i].v;
if ((depth[v]==-1)&&(E[i].flow>0))
{
depth[v]=depth[u]+1;
h++;
Q[h]=v;
}
}
}
while (t!=h);
if (depth[n*2+1]==-1)
return 0;
return 1;
}
int dfs(int u,int flow)
{
if (u==n*2+1)
return flow;
for (int &i=cur[u];i!=-1;i=Next[i])
{
int v=E[i].v;
if ((depth[v]==depth[u]+1)&&(E[i].flow>0))
{
int di=dfs(v,min(flow,E[i].flow));
if (di>0)
{
E[i].flow-=di;
E[i^1].flow+=di;
return di;
}
}
}
return 0;
}
Libre 6005 「网络流 24 题」最长递增子序列 / Luogu 2766 最长递增子序列问题(网络流,最大流)的更多相关文章
- Libre 6013 「网络流 24 题」负载平衡 (网络流,最小费用最大流)
Libre 6013 「网络流 24 题」负载平衡 (网络流,最小费用最大流) Description G 公司有n 个沿铁路运输线环形排列的仓库,每个仓库存储的货物数量不等.如何用最少搬运量可以使n ...
- Libre 6012 「网络流 24 题」分配问题 (网络流,费用流)
Libre 6012 「网络流 24 题」分配问题 (网络流,费用流) Description 有n件工作要分配给n个人做.第i个人做第j件工作产生的效益为\(c_{ij}\).试设计一个将n件工作分 ...
- Libre 6011 「网络流 24 题」运输问题 (网络流,最小费用最大流)
Libre 6011 「网络流 24 题」运输问题 (网络流,最小费用最大流) Description W 公司有m个仓库和n个零售商店.第i个仓库有\(a_i\)个单位的货物:第j个零售商店需要\( ...
- Libre 6010「网络流 24 题」数字梯形 (网络流,最大费用最大流)
Libre 6010「网络流 24 题」数字梯形 (网络流,最大费用最大流) Description 给定一个由n 行数字组成的数字梯形如下图所示.梯形的第一行有m 个数字.从梯形的顶部的m 个数字开 ...
- Libre 6009 「网络流 24 题」软件补丁 / Luogu 2761 软件安装问题 (最短路径,位运算)
Libre 6009 「网络流 24 题」软件补丁 / Luogu 2761 软件安装问题 (最短路径,位运算) Description T 公司发现其研制的一个软件中有 n 个错误,随即为该软件发放 ...
- Libre 6008 「网络流 24 题」餐巾计划 (网络流,最小费用最大流)
Libre 6008 「网络流 24 题」餐巾计划 (网络流,最小费用最大流) Description 一个餐厅在相继的N天里,第i天需要Ri块餐巾(i=l,2,-,N).餐厅可以从三种途径获得餐巾. ...
- Libre 6007 「网络流 24 题」方格取数 / Luogu 2774 方格取数问题 (网络流,最大流)
Libre 6007 「网络流 24 题」方格取数 / Luogu 2774 方格取数问题 (网络流,最大流) Description 在一个有 m*n 个方格的棋盘中,每个方格中有一个正整数.现要从 ...
- Libre 6006 「网络流 24 题」试题库 / Luogu 2763 试题库问题 (网络流,最大流)
Libre 6006 「网络流 24 题」试题库 / Luogu 2763 试题库问题 (网络流,最大流) Description 问题描述: 假设一个试题库中有n道试题.每道试题都标明了所属类别.同 ...
- Libre 6004 「网络流 24 题」圆桌聚餐(网络流,最大流)
Libre 6004 「网络流 24 题」圆桌聚餐(网络流,最大流) Description 假设有来自n个不同单位的代表参加一次国际会议.每个单位的代表数分别为 ri.会议餐厅共有m张餐桌,每张餐桌 ...
随机推荐
- 网络对抗技术 2017-2018-2 20152515 Exp4 恶意代码分析
1.实验后回答问题 (1)如果在工作中怀疑一台主机上有恶意代码,但只是猜想,所有想监控下系统一天天的到底在干些什么.请设计下你想监控的操作有哪些,用什么方法来监控. 答:- 我会使用sysmon工具来 ...
- 2015306 白皎 《网络攻防》EXP6 信息搜集与漏洞扫描
2015306 白皎 <网络攻防>EXP6 信息搜集与漏洞扫描 一.问题回答 (1)哪些组织负责DNS,IP的管理. 顶级的管理者是Internet Corporation for Ass ...
- Spring集成Swagger,Java自动生成Api文档
博主很懒... Swagger官网:http://swagger.io GitHub地址:https://github.com/swagger-api 官方注解文档:http://docs.swagg ...
- LNMP环境中WordPress程序伪静态解决方案
LNMP环境是目前我们国内站长使用的Linux VPS配置环境中使用较多的.作为新手我们很可能会看到老左类似的"LNMP安装教程"然后依葫芦画瓢的去安装VPS.我们是否有发现环境中 ...
- LORA---关于LORA的30个常见问题解答
1) 什么是LoRa调制? LoRa (Long Range,远距离)是一种调制技术,与同类技术相比,提供更长的通信距离.调制是基于扩频技术,线性调制扩频(CSS)的一个变种,具有前向纠错(FEC). ...
- [BZOJ4379][POI2015]Modernizacja autostrady[树的直径+换根dp]
题意 给定一棵 \(n\) 个节点的树,可以断掉一条边再连接任意两个点,询问新构成的树的直径的最小和最大值. \(n\leq 5\times 10^5\) . 分析 记断掉一条边之后两棵树的直径为 \ ...
- Reflux系列01:异步操作经验小结
写在前面 在实际项目中,应用往往充斥着大量的异步操作,如ajax请求,定时器等.一旦应用涉及异步操作,代码便会变得复杂起来.在flux体系中,让人困惑的往往有几点: 异步操作应该在actions还是s ...
- 巧用cheerio重构grunt-inline
grunt-inline是楼主之前写的一个插件,主要作用是把页面带了__inline标记的资源内嵌到html页面去.比如下面的这个script标签. <script src="main ...
- Azure 基础:Queue Storage
Azure Storage 是微软 Azure 云提供的云端存储解决方案,当前支持的存储类型有 Blob.Queue.File 和 Table. 笔者在前文中介绍了 File Storage 的基本用 ...
- 【Alpha】第七次Scrum meeting
今日任务一览: 姓名 今日完成任务 所耗时间 刘乾 今日没有做很多事...一天都在沟通细化需求与画电路图 2 鲁聃 生成物理报告实验页面的生成 Issue链接:https://github.com/b ...