网络流 之 P2766 最长不下降子序列问题
题目描述
«问题描述:
给定正整数序列x1,...,xn 。
(1)计算其最长不下降子序列的长度s。
(2)计算从给定的序列中最多可取出多少个长度为s的不下降子序列。
(3)如果允许在取出的序列中多次使用x1和xn,则从给定序列中最多可取出多少个长度为s的不下降子序列。
«编程任务:
设计有效算法完成(1)(2)(3)提出的计算任务。
输入输出格式
输入格式:
第1 行有1个正整数n,表示给定序列的长度。接下来的1 行有n个正整数n:x1, ..., xn。
输出格式:
第1 行是最长不下降子序列的长度s。第2行是可取出的长度为s 的不下降子序列个数。第3行是允许在取出的序列中多次使用x1和xn时可取出的长度为s 的不下降子序列个数。
输入输出样例
说明
500n≤500
最长不下降子序列
这个题目第一问显然是LIS
第二问和第三问就转化成最大流。
转化过程(理解了好久)
第二问:
建图,先求出f数组,f[i]表示到第i为的最长的不下降子序列,
然后因为第二问每一个数只能用一次,所以就把一个点拆成一个入点一个出点。
建图就是让f[i]==1的和s连在一起,f[i]==ans的和t连在一起,然后中间如果有
a[i]>=a[j]&&i>j&&f[i]=f[j]+1 这样的话就把 j 的出点和 i 的入点连在一起,这个就是建图过程。
接下来说说为什么这么建图,
首先只考虑第二问,因为每一个点只能用一次,所以就把点拆开,并且权值为1 ,然后因为只有f[i]==1
才会和s点相连,设f[i]==1的个数为x,所以这个就说明最多只能有x个答案,在这个基础上再看有没有从这个
点出发可以到达f[i]==ans的。
接下来说说为什么会 a[i]>=a[j]&&i>j&&f[i]=f[j]+1 这个j的出点和i的入点连在一起。
这个必须是这样子写的,因为只有这个样子到f[i]==ans 的过程中把中间的数字标记一次,不让别的再跑了。
例如说样例: 3 6 2 5 这个ans=2 第二问答案有两组就是 3 6 和 2 5,
3和2都与源点连起来了,6和5 都和汇点连起来了,3也会和6 5 连起来,2就只会和6 连起来,
然后这个答案可以是3 5 或者2 6 和2 5 ,很显然后面的才是最大流。
然后第三问 首先你要看清楚题目,题目说的只是x1和xn可以用无数多次,
所以这个就只要改成 s 到1 和1到n+1 和 n到 n+n if(f[n]==ans) n到 t 这些边改成无数次然后就再跑一次。
因为f[i]==1所以从s到1很有可能会跑很多次,所以,这个既然x1可以用无数多次,则要设s到1和1到1+n为无数多次
如果f[n]!=ans 则说明这个点不会和t连在一起,所以就不能连n到t,但是n到n+n可以连无数多次,不过好像没什么用。
因为n是最后一个
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
#include <vector>
#include <string>
#define inf 0x3f3f3f3f
using namespace std;
const int maxn = 1e5;
int s, t;
struct node
{
int from, to, cap, flow;
node(int from=,int to=,int cap=,int flow=):from(from),to(to),cap(cap),flow(flow){}
};
vector<node>e;
vector<int>G[maxn];
void add(int u,int v,int w)
{
e.push_back(node(u, v, w, ));
e.push_back(node(v, u, , ));
int m = e.size();
G[u].push_back(m - );
G[v].push_back(m - );
}
int a[maxn], dp[maxn];
int level[maxn], iter[maxn]; void bfs(int s)
{
memset(level, -, sizeof(level));
level[s] = ;
queue<int>que;
que.push(s);
while(!que.empty())
{
int u = que.front(); que.pop();
for(int i=;i<G[u].size();i++)
{
node &now = e[G[u][i]];
if(now.cap>now.flow&&level[now.to]<)
{
level[now.to] = level[u] + ;
que.push(now.to);
}
}
}
} int dfs(int u,int v,int f)
{
if (u == v) return f;
for(int &i=iter[u];i<G[u].size();i++)
{
node &now = e[G[u][i]];
if(now.cap>now.flow&&level[now.to]>level[u])
{
int d = dfs(now.to, v, min(f, now.cap - now.flow));
if(d>)
{
now.flow += d;
e[G[u][i] ^ ].flow -= d;
return d;
}
}
}
return ;
} int dinic()
{
int flow = ;
while()
{
bfs(s);
if (level[t] < ) return flow;
memset(iter, , sizeof(iter));
int f;
while ((f = dfs(s, t, inf)) > ) flow += f;
}
} int main()
{
int n;
cin >> n;
for (int i = ; i <= n; i++) cin >> a[i];
s = , t = * n + ;
int res = ;
for(int i=;i<=n;i++)
{
dp[i] = ;
for(int j=;j<i;j++)
{
if (a[j] <= a[i]) dp[i] = max(dp[i], dp[j] + );
}
res = max(res, dp[i]);
}
printf("%d\n", res);
for (int i = ; i <= n; i++) add(i, i + n, );
for (int i = ; i <= n; i++) if (dp[i] == ) add(s, i, );
for (int i = ; i <= n; i++) if (dp[i] == res) add(i+n, t, );
for(int i=;i<=n;i++)
{
for(int j=;j<i;j++)
{
if (a[i] >= a[j] && dp[i] == dp[j] + ) add(j + n, i, );
}
}
int ans = dinic();
printf("%d\n", ans);
add(s, , inf);
add(, + n, inf);
if (dp[n] == res) add(n, t, inf),add(n, n + n, inf);
int ech = dinic();
printf("%d\n", ech+ans);
return ;
}
网络流 之 P2766 最长不下降子序列问题的更多相关文章
- P2766 最长不下降子序列问题 网络流重温
P2766 最长不下降子序列问题 这个题目还是比较简单的,第一问就是LIS 第二问和第三问都是网络流. 第二问要怎么用网络流写呢,首先,每一个只能用一次,所以要拆点. 其次,我们求的是长度为s的不下降 ...
- 【24题】P2766最长不下降子序列问题
网络流二十四题 网络流是个好东西,希望我也会. 网络流?\(orz\ zsy!!!!!\) P2766 最长不下降子序列问题 考虑我们是如何\(dp\)这个\(LIS\)的. 我们是倒着推,设置\(d ...
- [**P2766** 最长不下降子序列问题](https://www.luogu.org/problemnew/show/P2766)
P2766 最长不下降子序列问题 考虑我们是如何\(dp\)这个\(LIS\)的. 我们是倒着推,设置\(dp(i)\)代表以\(i\)为起点的\(LIS\)是多少.转移太显然了 \[ dp(i)=m ...
- P2766 最长不下降子序列问题 网络流
link:https://www.luogu.org/problemnew/show/P2766 题意 给定正整数序列x1,...,xn . (1)计算其最长不下降子序列的长度s. (2)计算从给定的 ...
- P2766 [网络流24题]最长不下降子序列问题
ha~ «问题描述: 给定正整数序列$x_1,...,x_n$ .$n<=500$ 求(1)计算其最长不下降子序列的长度$s$. (2)计算从给定的序列中最多可取出多少个长度为$s$的不下降子序 ...
- 【Luogu】P2766最长不下降子序列问题(暴力网络流)
题目链接 水题qwq,数据都那么水. 我要是出数据的人我就卡$n^3$建图. qwq. 然而这么水的题我!居!然!没!有!1!A!!还!提!交!了!五!遍!!! md从现在开始要锻炼1A率了 看我从今 ...
- P2766 最长不下降子序列问题 题解(网络流)
题目链接 最长不下降子序列问题 解题思路 分成三小问解决. 第一小问,求\(LIS\),因为\(n<=500\),直接\(O(N^2)\)暴力求解即可. 第二三小问,建立模型用网络流求解. 对于 ...
- 网络流24题 P2766 最长不下降子序列问题
题目描述 «问题描述: 给定正整数序列x1,...,xn . (1)计算其最长不下降子序列的长度s. (2)计算从给定的序列中最多可取出多少个长度为s的不下降子序列. (3)如果允许在取出的序列中多次 ...
- 洛谷 P2766 最长不下降子序列问【dp+最大流】
死于开小数组的WA?! 第一问n方dp瞎搞一下就成,f[i]记录以i结尾的最长不下降子序列.记答案为mx 第二问网络流,拆点限制流量,s向所有f[i]为1的点建(s,i,1),所有f[i]为mx(i+ ...
随机推荐
- 【Spring源码分析系列】ApplicationContext 相关接口架构分析
[原创文章,转载请注明出处][本文地址]http://www.cnblogs.com/zffenger/p/5813470.html 在使用Spring的时候,我们经常需要先得到一个Applicati ...
- 你可能需要为你的 APP 适配 iOS 11
本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:https://mp.weixin.qq.com/s/AZFrqL9dnlgA6Vt2sVhxIw 作者:s ...
- 以Windows服务方式运行ASP.NET Core程序
我们对ASP.NET Core的使用已经进行了相当一段时间了,大多数时候,我们的Web程序都是发布到Linux主机上的,当然了,偶尔也有需求要发布到Windows主机上,这样问题就来了,难道直接以控制 ...
- Dubbo 支持哪些序列化协议?
面试题 dubbo 支持哪些通信协议?支持哪些序列化协议?说一下 Hessian 的数据结构?PB 知道吗?为什么 PB 的效率是最高的? 面试官心理分析 上一个问题,说说 dubbo 的基本工作原理 ...
- RecyclerView实现一个页面有多种item,每个item有多个view,并且可以让任意item的任意view自定义监听,通过接口方法进行触发操作
百度了很多贴子,看着大佬的博客,模仿尝试,最终都是以失败告终,api可能版本不一样, 毕竟博客大佬都是7~8前写的,日期新点的都是好几年前了,多次尝试,还是报出莫名其妙的错. 哎,忧伤. 翻阅各种资料 ...
- 【TensorFlow篇】--Tensorflow框架可视化之Tensorboard
一.前述 TensorBoard是tensorFlow中的可视化界面,可以清楚的看到数据的流向以及各种参数的变化,本文基于一个案例讲解TensorBoard的用法. 二.代码 设计一个MLP多层神经网 ...
- 高效并发unsafe-星耀
定义 Unsafe类是在sun.misc包下,不属于Java标准.但是很多Java的基础类库,包括一些被广泛使用的高性能开发库都是基于Unsafe类开发的,比如Netty.Cassandra.Hado ...
- Docker中完成Jenkins的安装
去年就开始学习采用Docker+Jenkins+.Net Core搭建生成式流水线,一直拖到现在,也没有彻底的好好静下来去总结总结.趁着现在对自己的严格要求下,逐渐开始重视自我总结,以此来巩固逐渐失去 ...
- 学习ASP.NET Core Razor 编程系列十八——并发解决方案
学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...
- kernel 进阶API
1. #define cond_resched() ({ \ ___might_sleep(__FILE__, __LINE__, ); \ _cond_resched(); \ }) int __s ...