acwing-2180. 最长递增子序列问题(最大流+拆点+最长上升子序列)

acwing-2180. 最长递增子序列问题(最大流+拆点+最长上升子序列)给定正整数序列 x1,⋯,xn。计算其最长递增子序列的长度 s。计算从给定的序列中最多可取出多少个长度为 s 的递增子序列。(给定序列中的每个元素最多只能被取出使用一次)如果允许在取出的序列中多次使用 x1 和 xn,则从给定序列中最多可取出多少个长度为 s 的递增子序列。注意:递增指非严格递增。输入格式第 1 行有 1 个正整数 n,表示给定序列的长度。接下来的 1 行有 n 个正整数 x1,⋯,xn。输出格式第 1 行输出最长递增子序列的长度 s。第 2 行输出可取出的长度为 s 的

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

给定正整数序列 x1,⋯,xn。

计算其最长递增子序列的长度 s。
计算从给定的序列中最多可取出多少个长度为 s 的递增子序列。(给定序列中的每个元素最多只能被取出使用一次)
如果允许在取出的序列中多次使用 x1 和 xn,则从给定序列中最多可取出多少个长度为 s 的递增子序列。
注意:递增指非严格递增。

输入格式
第 1 行有 1 个正整数 n,表示给定序列的长度。

接下来的 1 行有 n 个正整数 x1,⋯,xn。

输出格式
第 1 行输出最长递增子序列的长度 s。

第 2 行输出可取出的长度为 s 的递增子序列个数。

第 3 行输出允许在取出的序列中多次使用 x1 和 xn 时可取出的长度为 s 的递增子序列个数。

数据范围
1≤n≤500

输入样例:
4
3 6 2 5
输出样例:
2
2
3

题解
当一个点只能被选一次的时候可以使用拆点的技术,同理可以选择k次的话,就从入点到出点连接一条流为K的边。注意源点对x1的影响

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1010, M = 251010, INF = 1e8;
int n, S, T;
int h[N], e[M], f[M], ne[M], idx;
int q[N], d[N], cur[N];
int g[N], w[N];
void add(int a, int b, int c)
{ 

e[idx] = b, f[idx] = c, ne[idx] = h[a], h[a] = idx ++ ;
e[idx] = a, f[idx] = 0, ne[idx] = h[b], h[b] = idx ++ ;
}
bool bfs()
{ 

int hh = 0, tt = 0;
memset(d, -1, sizeof d);
q[0] = S, d[S] = 0, cur[S] = h[S];
while (hh <= tt)
{ 

int t = q[hh ++ ];
for (int i = h[t]; ~i; i = ne[i])
{ 

int ver = e[i];
if (d[ver] == -1 && f[i])
{ 

d[ver] = d[t] + 1;
cur[ver] = h[ver];
if (ver == T) return true;
q[ ++ tt] = ver;
}
}
}
return false;
}
int find(int u, int limit)
{ 

if (u == T) return limit;
int flow = 0;
for (int i = cur[u]; ~i && flow < limit; i = ne[i])
{ 

cur[u] = i;
int ver = e[i];
if (d[ver] == d[u] + 1 && f[i])
{ 

int t = find(ver, min(f[i], limit - flow));
if (!t) d[ver] = -1;
f[i] -= t, f[i ^ 1] += t, flow += t;
}
}
return flow;
}
int dinic()
{ 

int r = 0, flow;
while (bfs()) while (flow = find(S, INF)) r += flow;
return r;
}
int main()
{ 

scanf("%d", &n);
S = 0, T = n * 2 + 1;
memset(h, -1, sizeof h);
for (int i = 1; i <= n; i ++ ) scanf("%d", &w[i]);
int s = 0;
for (int i = 1; i <= n; i ++ )
{ 

add(i, i + n, 1);
g[i] = 1;
for (int j = 1; j < i; j ++ )
if (w[j] <= w[i])
g[i] = max(g[i], g[j] + 1);
for (int j = 1; j < i; j ++ )
if (w[j] <= w[i] && g[j] + 1 == g[i])
add(n + j, i, 1);
s = max(s, g[i]);
if (g[i] == 1) add(S, i, 1);
}
for (int i = 1; i <= n; i ++ )
if (g[i] == s)
add(n + i, T, 1);
printf("%d\n", s);
if (s == 1) printf("%d\n%d\n", n, n);
else
{ 

int res = dinic();
printf("%d\n", res);
for (int i = 0; i < idx; i += 2)
{ 

int a = e[i ^ 1], b = e[i];
if (a == S && b == 1) f[i] = INF;
else if (a == 1 && b == n + 1) f[i] = INF;
else if (a == n && b == n + n) f[i] = INF;
else if (a == n + n && b == T) f[i] = INF;
}
printf("%d\n", res + dinic());
}
return 0;
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/168571.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 极大似然、最小二乘和梯度下降

    极大似然、最小二乘和梯度下降

    2021年11月19日
  • mac怎么装linux双系统_双系统linux和windows

    mac怎么装linux双系统_双系统linux和windows第一步:格式化U盘第二步:下载系统,这里我选择的是基于manjaro第三步:将iso镜像转成dmg格式第四步:写入镜像第五步:分空间第六步:关闭OSX的-SIP保护第七步:安装refind第八步:重启按住option键安装系统第九步:重启查看结果第一步:格式化U盘第二步:下载系统,这里我选择的是基于manjaro第三步:…

  • 如何学习Android开发编程-初学者的5个步骤

    如何学习Android开发编程-初学者的5个步骤如何学习Android开发编程-初学者的5个步骤在本文中,您将发现如何学习Android开发编程。了解如何成为一名Android开发人员,并按照以下5个步骤操作。您是否想学习Android?如果是,但您不知道如何操作,则此文章适合您。它将帮助您以Android开发人员的身份开始冒险。准备?321如何学习Android开发-初学者的6个关键步骤1.看看…

  • fat文件系统中,文件的物理结构_磁盘的文件系统结构

    fat文件系统中,文件的物理结构_磁盘的文件系统结构在这个系类的开篇还是先说一下文件系统是什么吧。首先来介绍一下对u盘的格式化这个操作,格式化不是仅仅删除了所有文件,还为接下的来文件存储约定了一种存放格式,这种约定的文件存放格式就叫做文件系统。再用最通俗的说法简要介绍一下,磁盘如sd卡只能存放0和1这两种二进制状态序列,数字文件本质上也是一串0和1的序列。那么磁盘存储文件怎么存放呢?你说这个简单,把一个个的文件紧挨着排列在磁盘中不就可以了吗。那么,…

    2022年10月31日
  • 武侠世界2-try catch思考

    以前一直不知道trycatch具体应用到什么地方,之前待过的几家公司也看不到有类似的代码。从网上搜来的,描述trycatch优点有下面几点。1、把错误处理和真正的工作分开来;  2、代码更易组织,更清晰,复杂的工作任务更容易实现;  3、毫无疑问,更安全了,不至于由于一些小的疏忽而使程序意外崩溃了;  4、由于C++中的trycatch可以分层嵌套,所以它…

  • 关于开源的RTP——jrtplib的使用

    关于开源的RTP——jrtplib的使用

    2021年11月17日

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号