洛谷P2766 最长递增子序列问题
https://www.luogu.org/problemnew/show/P2766
注:题目描述有误,本题求的是最长不下降子序列
方案无限多时输出 n
网络流求方案数,长见识了
第一问:
DP
同时得到f[i] 表示 以第i个数为开头的最长不下降子序列长度
第二问:
每个点拆出2个点 i<<1,i<<1|1,之间连流量为1的边
如果f[i]==最长长度,源点向i<<1连流量为1的边
如果f[i]==1,i<<1|1向汇点连流量为1的边
如果 i<j && f[i]==f[j]+1 i<<1 向j<<1|1 连流量为1的边
这样每一条增广路就是一个方案
第三问:
源点向1<<1,向n<<1连的边,
1<<1|1,n<<1|1向汇点连的边,
1<<1与1<<1|1,n<<1与n<<1|1 之间的边
流量改为inf
小错误:
特判序列为单调下降序列
因为 源点会向每个1<<1连流量为inf 的边
1<<1|1又会向汇点连inf的边
这样导致第三问跑出负无穷,第9、10 测试点挂了的可能是这个原因
- #include<queue>
- #include<cstdio>
- #include<cstring>
- #include<iostream>
- #include<algorithm>
- using namespace std;
- #define N 1011
- #define M 300001
- const int inf=2e9;
- int n;
- int a[];
- int max_len;
- int f[];
- int tot=;
- int front[N],to[M<<],nxt[M<<],val[M<<],from[M<<];
- int lev[N],num[N];
- int path[N];
- int cur[N];
- int src,decc;
- void read(int &x)
- {
- x=; char c=getchar();
- while(!isdigit(c)) c=getchar();
- while(isdigit(c)) { x=x*+c-''; c=getchar(); }
- }
- void dp()
- {
- int mx;
- for(int i=n;i;--i)
- {
- mx=;
- for(int j=i+;j<=n;++j)
- if(a[j]>=a[i]) mx=max(mx,f[j]);
- f[i]=mx+;
- max_len=max(max_len,f[i]);
- }
- cout<<max_len;
- }
- void add(int u,int v,int w)
- {
- to[++tot]=v; nxt[tot]=front[u]; front[u]=tot; val[tot]=w; from[tot]=u;
- to[++tot]=u; nxt[tot]=front[v]; front[v]=tot; val[tot]=; from[tot]=v;
- // cout<<u<<' '<<v<<' '<<w<<'\n';
- }
- void build()
- {
- for(int i=;i<=n;++i) add(i<<,i<<|,);
- for(int i=;i<=n;++i)
- if(f[i]==max_len) add(src,i<<,);
- for(int i=;i<=n;++i)
- if(f[i]==) add(i<<|,decc,);
- for(int i=;i<=n;++i)
- for(int j=;j<i;++j)
- if(a[j]<=a[i] && f[i]==f[j]-) add(j<<|,i<<,);
- }
- void rebuild()
- {
- tot=;
- memset(front,,sizeof(front));
- add(<<,<<|,inf);
- add(n<<,n<<|,inf);
- for(int i=;i<n;++i) add(i<<,i<<|,);
- if(f[]==max_len) add(src,<<,inf);
- if(f[n]==max_len) add(src,n<<,inf);
- for(int i=;i<n;++i)
- if(f[i]==max_len) add(src,i<<,);
- if(f[]==) add(<<|,decc,inf);
- if(f[n]==) add(n<<|,decc,inf);
- for(int i=;i<n;++i)
- if(f[i]==) add(i<<|,decc,);
- for(int i=;i<=n;++i)
- for(int j=;j<i;++j)
- if(a[j]<=a[i] && f[i]==f[j]-) add(j<<|,i<<,);
- }
- bool bfs()
- {
- for(int i=src;i<=decc;++i) lev[i]=decc;
- queue<int>q;
- q.push(decc);
- lev[decc]=;
- int now,t;
- while(!q.empty())
- {
- now=q.front();
- q.pop();
- for(int i=front[now];i;i=nxt[i])
- {
- t=to[i];
- if(lev[t]==decc && val[i^])
- {
- lev[t]=lev[now]+;
- q.push(t);
- }
- }
- }
- return lev[src]!=decc;
- }
- int augment()
- {
- int flow=inf,now=decc;
- int i;
- while(now!=src)
- {
- i=path[now];
- flow=min(flow,val[i]);
- now=from[i];
- }
- now=decc;
- while(now!=src)
- {
- i=path[now];
- val[i]-=flow;
- val[i^]+=flow;
- now=from[i];
- }
- return flow;
- }
- void isap()
- {
- if(!bfs())
- {
- cout<<'\n'<<;
- return;
- }
- memset(num,,sizeof(num));
- for(int i=src;i<=decc;++i) num[lev[i]]++;
- int flow=;
- int now=src,t;
- while(lev[src]<decc)
- {
- if(now==decc)
- {
- flow+=augment();
- now=src;
- }
- bool advanced=false;
- for(int i=front[now];i;i=nxt[i])
- {
- t=to[i];
- if(lev[t]==lev[now]- && val[i])
- {
- advanced=true;
- path[t]=i;
- cur[now]=i;
- now=t;
- break;
- }
- }
- if(!advanced)
- {
- int mi=decc;
- for(int i=front[now];i;i=nxt[i])
- if(val[i]) mi=min(mi,lev[to[i]]);
- if(!num[--lev[now]]) break;
- num[lev[now]=mi+]++;
- cur[now]=front[now];
- if(now!=src) now=from[path[now]];
- }
- }
- cout<<'\n'<<flow;
- }
- int main()
- {
- read(n);
- src=; decc=(n<<|)+;
- for(int i=;i<=n;++i) read(a[i]);
- dp();
- if(max_len==)
- {
- cout<<'\n'<<n<<'\n'<<n;
- return ;
- }
- build();
- isap();
- rebuild();
- isap();
- }
题目描述
«问题描述:
给定正整数序列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 的递增子序列个数。
输入输出样例
说明
n\le 500n≤500
洛谷P2766 最长递增子序列问题的更多相关文章
- 洛谷 [p1439] 最长公共子序列 (NlogN)
可以发现只有当两个序列中都没有重复元素时(1-n的排列)此种优化才是高效的,不然可能很不稳定. 求a[] 与b[]中的LCS 通过记录lis[i]表示a[i]在b[]中的位置,将LCS问题转化为最长上 ...
- 洛谷P3402 最长公共子序列
题目背景 DJL为了避免成为一只咸鱼,来找Johann学习怎么求最长公共子序列. 题目描述 经过长时间的摸索和练习,DJL终于学会了怎么求LCS.Johann感觉DJL孺子可教,就给他布置了一个课后作 ...
- 洛谷P1439 最长公共子序列(LCS问题)
题目描述 给出1-n的两个排列P1和P2,求它们的最长公共子序列. 输入输出格式 输入格式: 第一行是一个数n, 接下来两行,每行为n个数,为自然数1-n的一个排列. 输出格式: 一个数,即最长公共子 ...
- 洛谷P2766 最长不下降子序列问题(最大流)
传送门 第一问直接$dp$解决,求出$len$ 然后用$f[i]$表示以$i$为结尾的最长不下降子序列长度,把每一个点拆成$A_i,B_i$两个点,然后从$A_i$向$B_i$连容量为$1$的边 然后 ...
- 洛谷 P2766 最长不下降子序列问【dp+最大流】
死于开小数组的WA?! 第一问n方dp瞎搞一下就成,f[i]记录以i结尾的最长不下降子序列.记答案为mx 第二问网络流,拆点限制流量,s向所有f[i]为1的点建(s,i,1),所有f[i]为mx(i+ ...
- 洛谷 [P2766] 最长不下降子序列问题
啊啊啊,再把MAXN和MAXM搞反我就退役 层次图求不相交路径数 第一问简单DP 第二问想办法把每一个不上升子序列转化成DAG上的一条路径,就转换成了求不相交路径数 因为每一个数只能用一次,所以要拆点 ...
- 洛谷P2766 最长不下降子序列问题 网络流_DP
Code: #include<cstdio> #include<iostream> #include<vector> #include<algorithm&g ...
- (转载)最长递增子序列 O(NlogN)算法
原博文:传送门 最长递增子序列(Longest Increasing Subsequence) 下面我们简记为 LIS. 定义d[k]:长度为k的上升子序列的最末元素,若有多个长度为k的上升子序列,则 ...
- 最长公共子序列(LCS)和最长递增子序列(LIS)的求解
一.最长公共子序列 经典的动态规划问题,大概的陈述如下: 给定两个序列a1,a2,a3,a4,a5,a6......和b1,b2,b3,b4,b5,b6.......,要求这样的序列使得c同时是这两个 ...
随机推荐
- Leetcode题库——24.两两交换链表中的节点
@author: ZZQ @software: PyCharm @file: swapPairs.py @time: 2018/10/20 19:49 说明:给定一个链表,两两交换其中相邻的节点,并返 ...
- Leetcode题库——17.电话号码的字母组合
@author: ZZQ @software: PyCharm @file: letterCombinations.py @time: 2018/10/18 18:33 要求:给定一个仅包含数字 2- ...
- 微服务负载均衡 —— ribbon
负载均衡是系统高可用.缓解网络流量和处理能力扩容的重要手段,广义的负载均衡指的是服务端负载均衡,如硬件负载均衡(F5)和软件负载均衡(Nginx).负载均衡设备会维护一份可用的服务器的信息,当客户端请 ...
- C# 通过http post 请求上传图片和参数
一.C# Winform或控制台 /// <summary> /// 通过http上传图片及传参数 /// </summary> /// <param name=&quo ...
- 软工网络15团队作业8——Beta阶段敏捷冲刺(day1)
第 1 篇 Scrum 冲刺博客 1. 介绍小组新加入的成员,Ta担任的角色 --给出让ta担当此角色的理由 小组新加入的成员:3085叶金蕾 担任的角色:测试/用户体验/开发 理由:根据小组讨论以及 ...
- requests爬取豆瓣热门电视剧
# *_*coding:utf-8 *_* import requests payload = {'key1': 'value1', 'key2': 'value2'} headers = {'use ...
- 通过ClientDataSet复制表的结构及数据
1. 需要2个ClientDataSet组件: 2. clientDataSet1连接目标表,clientDataSet2连接源表,如果无法直接连接,使用DataSetProvider进行桥接: ...
- UVA11248_Frequency Hopping
给一个有向网络,求其1,n两点的最大流量是否不小于C,如果小于,是否可以通过修改一条边的容量使得最大流量不小于C? 首先对于给定的网络,我们可以先跑一遍最大流,然后先看流量是否大于C. 然后保存跑完第 ...
- spring1 注册value与ref的区别
- Day22-中间件
1.中间件,在其它程序中,有的叫管道,有的叫http handler.下面是原生的中间件 2.自己也可以写中间件 2.1 写中间件,新建文件夹Middle,新建m1.py 2.2 在setting里注 ...