【24题】P2766最长不下降子序列问题
网络流二十四题
网络流是个好东西,希望我也会。
网络流?\(orz\ zsy!!!!!\)
P2766 最长不下降子序列问题
考虑我们是如何\(dp\)这个\(LIS\)的。
我们是倒着推,设置\(dp(i)\)代表以\(i\)为起点的\(LIS\)是多少。转移太显然了
\]
想一想一个合法的\(LIS\)方案代表着什么,代表着它是由这个式子一个一个推出来的。
考虑一个数字只能用一次,那么我们直接拆成两个点\(v_0,v_1\)分别代表一个数字的入度和出度,连一条\(v_1v_2,cap=1\)的边。这样就模拟了一个数字可以被前面多个都相中但是只能往后面相中一个的要求。
考虑如何构造方案,这个东西是个灵感,就是还原\(dp\) 转移的过程,这样就可以得到合法方案。
模型这样建立
\\
(S,i_0,inf),dp(i)=1
\\
(i_1,T,inf),dp(k)=ans
\]
这样就好了。先咕咕咕。
#include<bits/stdc++.h>
using namespace std;typedef long long ll;
#define DRP(t,a,b) for(register int t=(a),edd=(b);t>=edd;--t)
#define RP(t,a,b) for(register int t=(a),edd=(b);t<=edd;++t)
#define ERP(t,a) for(register int t=head[a];t!=-1;t=e[t].nx)
#define midd register int mid=(l+r)>>1
#define TMP template < class ccf >
#define lef l,mid,pos<<1
#define rgt mid+1,r,pos<<1|1
#define pushup(pos) (seg[pos]=seg[pos<<1]+seg[pos<<1|1])
TMP inline ccf qr(ccf b){
register char c=getchar();register int q=1;register ccf x=0;
while(c<48||c>57)q=c==45?-1:q,c=getchar();
while(c>=48&&c<=57)x=x*10+c-48,c=getchar();
return q==-1?-x:x;}
TMP inline ccf Max(ccf a,ccf b){return a<b?b:a;}
TMP inline ccf Min(ccf a,ccf b){return a<b?a:b;}
TMP inline ccf Max(ccf a,ccf b,ccf c){return Max(a,Max(b,c));}
TMP inline ccf Min(ccf a,ccf b,ccf c){return Min(a,Min(b,c));}
TMP inline void READ(ccf* _arr,int _n){RP(t,1,_n)_arr[t]=qr((ccf)1);}
//----------------------template&IO---------------------------
const int maxn=5e2+15;
const int maxm=maxn<<3;
int dp[maxn];
int data[maxn];
const int inf=0x3f3f3f3f;
int n,S,T;
struct E{
int to,w,nx;
}e[maxm<<1],tmp[maxm<<1];
int cnt(-1);
int head[maxm];
int id[maxn][2];
int sz;
int ans1,ans2,ans3;
int d[maxm];
int cur[maxm];
inline void add(int fr,int to,int w,bool f){
e[++cnt]=(E){to,w,head[fr]};head[fr]=cnt;
if(f) add(to,fr,0,0);
}
queue < int > q;
inline bool bfs(){
while(not q.empty()) q.pop();
RP(t,1,sz) cur[t]=head[t],d[t]=inf+1;
d[S]=1;q.push(S);
while(not q.empty()){
register int now=q.front();q.pop();
if(now==T) break;
ERP(t,now){
if(d[e[t].to]>d[now]+1&&e[t].w>0){
d[e[t].to]=d[now]+1;
q.push(e[t].to);
}
}
}
return d[T]<inf;
}
int dfs(int now,int fl){
if(now==T||!fl) return fl;
register int ret=0;
for(register int t=cur[now],en;t!=-1;t=e[t].nx){
cur[now]=t;
if(d[e[t].to]==d[now]+1){
en=dfs(e[t].to,Min(fl,e[t].w));
if(en){e[t].w-=en;e[t^1].w+=en;fl-=en;ret+=en;}
if(not fl)break;
}
}return ret;
}
inline void dinic(int& ret){while(bfs()) ret+=dfs(S,inf);}
int main(){
#ifndef ONLINE_JUDGE
freopen("in.in","r",stdin);
freopen("out.out","w",stdout);
#endif
memset(head,-1,sizeof head);
n=qr(1);
READ(data,n);
RP(t,1,n) dp[t]=1;ans1=1;
DRP(t,n,1) RP(i,t+1,n) if(data[t]<=data[i]) ans1=Max((dp[t]=Max(dp[t],dp[i]+1)),ans1);
S=++sz;T=++sz;
DRP(t,n,1){
id[t][0]=++sz;id[t][1]=++sz;
add(id[t][0],id[t][1],1,1);
if(dp[t]==1){add(id[t][1],T,inf,1);}
if(dp[t]==ans1){add(S,id[t][0],inf,1);}
RP(i,t+1,n) if(data[i]>=data[t]&&dp[i]+1==dp[t]) add(id[t][1],id[i][0],1,1);
}
RP(t,0,cnt) tmp[t]=e[t];
dinic(ans2);
RP(t,0,cnt) e[t]=tmp[t];
add(id[1][0],id[1][1],inf,1);
add(id[n][0],id[n][1],inf,1);
dinic(ans3);
if(ans1==1) ans2=ans3=n;
printf("%d\n%d\n%d\n",ans1,ans2,ans3);
return 0;
}
【24题】P2766最长不下降子序列问题的更多相关文章
- 网络流24题 P2766 最长不下降子序列问题
题目描述 «问题描述: 给定正整数序列x1,...,xn . (1)计算其最长不下降子序列的长度s. (2)计算从给定的序列中最多可取出多少个长度为s的不下降子序列. (3)如果允许在取出的序列中多次 ...
- [**P2766** 最长不下降子序列问题](https://www.luogu.org/problemnew/show/P2766)
P2766 最长不下降子序列问题 考虑我们是如何\(dp\)这个\(LIS\)的. 我们是倒着推,设置\(dp(i)\)代表以\(i\)为起点的\(LIS\)是多少.转移太显然了 \[ dp(i)=m ...
- P2766 最长不下降子序列问题 网络流重温
P2766 最长不下降子序列问题 这个题目还是比较简单的,第一问就是LIS 第二问和第三问都是网络流. 第二问要怎么用网络流写呢,首先,每一个只能用一次,所以要拆点. 其次,我们求的是长度为s的不下降 ...
- P2766 最长不下降子序列问题 网络流
link:https://www.luogu.org/problemnew/show/P2766 题意 给定正整数序列x1,...,xn . (1)计算其最长不下降子序列的长度s. (2)计算从给定的 ...
- 【题解】Luogu P2766 最长不下降子序列问题
原题传送门 实际还是比较套路的建图 先暴力dp一下反正数据很小 第一小问的答案即珂以求出数列的最长不下降子序列的长度s 考虑第二问如何做: 将每个点拆点 从前向后连一条流量为1的边 如果以它为终点的最 ...
- 【Luogu】P2766最长不下降子序列问题(暴力网络流)
题目链接 水题qwq,数据都那么水. 我要是出数据的人我就卡$n^3$建图. qwq. 然而这么水的题我!居!然!没!有!1!A!!还!提!交!了!五!遍!!! md从现在开始要锻炼1A率了 看我从今 ...
- 网络流 之 P2766 最长不下降子序列问题
题目描述 «问题描述: 给定正整数序列x1,...,xn . (1)计算其最长不下降子序列的长度s. (2)计算从给定的序列中最多可取出多少个长度为s的不下降子序列. (3)如果允许在取出的序列中多次 ...
- P2766 最长不下降子序列问题
题目描述 «问题描述: 给定正整数序列x1,...,xn . (1)计算其最长不下降子序列的长度s. (2)计算从给定的序列中最多可取出多少个长度为s的不下降子序列. (3)如果允许在取出的序列中多次 ...
- 洛谷P2766 最长不下降子序列问题(最大流)
传送门 第一问直接$dp$解决,求出$len$ 然后用$f[i]$表示以$i$为结尾的最长不下降子序列长度,把每一个点拆成$A_i,B_i$两个点,然后从$A_i$向$B_i$连容量为$1$的边 然后 ...
随机推荐
- RESTful详解(非原创)
文章大纲 一.什么是RESTful二.为什么要使用RESTful三.RESTful实战四.项目源码下载五.参考文章 一.什么是RESTful 1. RESTful概念 REST 是面向资源的, ...
- 怎么把一个整数转化为3个十六进制字节 delphi
如何把一个整数转化为3个十六进制字节 delphi比如把整数149259(都是6位数据整型数) 转换为十六进制为2470B然后再分开为三个字节02 47 0B,求实现代码示例var ID: Integ ...
- iOS申请证书,Certificates, Identifiers &Profiles 简介 - 申请证书
在真机调试以及发布应用时,要申请证书,我们必须知道Certificates, Identifiers ,Profiles 是什么含义,下面对它们做简单介绍,以及如果申请证书. Certificates ...
- Python中xml、字典、json、类四种数据的转换
最近学python,觉得python很强很大很强大,写一个学习随笔,当作留念注:xml.字典.json.类四种数据的转换,从左到右依次转换,即xml要转换为类时,先将xml转换为字典,再将字典转换为j ...
- 左手系,右手系,row major, column major
http://www.cnblogs.com/minggoddess/p/3672863.html dx 左手系 row major ogl 右手系 column major 差了个 matrix ...
- linux中at命令
名称 : linux at命令 使用权限 : 所有使用者 使用方式 : at -V [-q queue] [-f file] [-mldbv] TIME 说明 : linux at命令可以让使用者指定 ...
- 微信小程序 - 答题进度条
关于进度条的话,我是使用官方原生的progress的. 关于进度progress接受保留2位小数(从后端获取到平均值,再item循环出来) js wxml
- Oracle 复制表创建的sql语句
http://cache.baiducontent.com/c?m=9d78d513d99e01fc09b3c3690d67c0161343f0652ba1d4020ed08449e3732b4250 ...
- Struts2学习五----------指定多个配置文件
© 版权声明:本文为博主原创文章,转载请注明出处 指定多个配置文件 - 在Struts2配置文件中使用include可指定多个配置文件 实例 1.项目结构 2.pom.xml <project ...
- iOS开发人员程序许可协议
请细致阅读以下的许可协议条款和条件之前下载或使用苹果软件. 这些条款和条件构成你和苹果之间的法律协议. iOS开发人员程序许可协议 目的 你想使用苹果软件(例如以下定义)来开发一个或多个应 ...