【网络流24题】最长递增子序列问题

本文介绍如何使用网络流解决最长递增子序列问题,包括第一问的基本DP解法,第二问的网络流应用,以及第三问的变化处理。通过在特定OJ上测试,确保解法有效。
摘要由CSDN通过智能技术生成

(网络流24题大多需要spj,所以需要一个有spj的oj,本系列代码均在www.oj.swust.edu.cn测试通过)
这道题据说在codeforces上的数据变成了最长不降,但是本文附上的oj没有这种情况。
这道题的题意就是求出最长上升序列长度,然后每个数只能取一个的情况下最多有多少种方案能取出这么长的序列,第一个数和最后一个数无限多的时候能取出多少个。
首先第一问dp就可以了,而且数据不大,最简单的dp即可。
然后第二问出现了一个数只能选一次的问题,那么就到了网络流的领域了,我们这样实现,将一个点拆分为一个入点和一个出点,入点和出点之间连一条1的流,如果以一个数为尾的最长序列长度为第一问答案的话,那么就从源点向该点连一条容量为1的流,如果最长序列长度为1的话就向汇点连接一条容量为一的流,两个点满足i < j && a[i] < a[j] && f[j]==f[i]+1 则从j向i连接一条容量为1的流,这样的话每一条流都是一个最长的序列,有几条这样的序列第二问的答案就是几。
第三问主要的变化就是1和n的数量发生了变化,那我们只需要将(1,1),(n,n)(s,1)(1,t)(s,n)(n,t)(如果有的话)的流量改为INF再求一边增广路即可。
注意当最长上升子序列为1的情况,这时候理论方案为无穷大(因为1,n无限多),但是根据数据来看只算了一个,将答案取余INF即可

#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<ctime>
#include<cstring>
#include<string>
#include<iomanip>
#include<iostream>
#include<algorithm>
using namespace std;
#define INF 100000000
struct bian
{
    int l,r,f;
}a[
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值