题目描述

«问题描述:

给定正整数序列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 的不下降子序列个数。

输入输出样例

输入样例#1: 复制

4
3 6 2 5
输出样例#1: 复制

2
2
3

说明

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 最长不下降子序列问题的更多相关文章

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

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

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

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

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

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

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

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

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

    ha~ «问题描述: 给定正整数序列$x_1,...,x_n$ .$n<=500$ 求(1)计算其最长不下降子序列的长度$s$. (2)计算从给定的序列中最多可取出多少个长度为$s$的不下降子序 ...

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

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

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

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

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

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

  9. 洛谷 P2766 最长不下降子序列问【dp+最大流】

    死于开小数组的WA?! 第一问n方dp瞎搞一下就成,f[i]记录以i结尾的最长不下降子序列.记答案为mx 第二问网络流,拆点限制流量,s向所有f[i]为1的点建(s,i,1),所有f[i]为mx(i+ ...

随机推荐

  1. 【Spring源码分析系列】ApplicationContext 相关接口架构分析

    [原创文章,转载请注明出处][本文地址]http://www.cnblogs.com/zffenger/p/5813470.html 在使用Spring的时候,我们经常需要先得到一个Applicati ...

  2. 你可能需要为你的 APP 适配 iOS 11

    本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:https://mp.weixin.qq.com/s/AZFrqL9dnlgA6Vt2sVhxIw 作者:s ...

  3. 以Windows服务方式运行ASP.NET Core程序

    我们对ASP.NET Core的使用已经进行了相当一段时间了,大多数时候,我们的Web程序都是发布到Linux主机上的,当然了,偶尔也有需求要发布到Windows主机上,这样问题就来了,难道直接以控制 ...

  4. Dubbo 支持哪些序列化协议?

    面试题 dubbo 支持哪些通信协议?支持哪些序列化协议?说一下 Hessian 的数据结构?PB 知道吗?为什么 PB 的效率是最高的? 面试官心理分析 上一个问题,说说 dubbo 的基本工作原理 ...

  5. RecyclerView实现一个页面有多种item,每个item有多个view,并且可以让任意item的任意view自定义监听,通过接口方法进行触发操作

    百度了很多贴子,看着大佬的博客,模仿尝试,最终都是以失败告终,api可能版本不一样, 毕竟博客大佬都是7~8前写的,日期新点的都是好几年前了,多次尝试,还是报出莫名其妙的错. 哎,忧伤. 翻阅各种资料 ...

  6. 【TensorFlow篇】--Tensorflow框架可视化之Tensorboard

    一.前述 TensorBoard是tensorFlow中的可视化界面,可以清楚的看到数据的流向以及各种参数的变化,本文基于一个案例讲解TensorBoard的用法. 二.代码 设计一个MLP多层神经网 ...

  7. 高效并发unsafe-星耀

    定义 Unsafe类是在sun.misc包下,不属于Java标准.但是很多Java的基础类库,包括一些被广泛使用的高性能开发库都是基于Unsafe类开发的,比如Netty.Cassandra.Hado ...

  8. Docker中完成Jenkins的安装

    去年就开始学习采用Docker+Jenkins+.Net Core搭建生成式流水线,一直拖到现在,也没有彻底的好好静下来去总结总结.趁着现在对自己的严格要求下,逐渐开始重视自我总结,以此来巩固逐渐失去 ...

  9. 学习ASP.NET Core Razor 编程系列十八——并发解决方案

    学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...

  10. kernel 进阶API

    1. #define cond_resched() ({ \ ___might_sleep(__FILE__, __LINE__, ); \ _cond_resched(); \ }) int __s ...