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 测试点挂了的可能是这个原因

  1. #include<queue>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<iostream>
  5. #include<algorithm>
  6.  
  7. using namespace std;
  8.  
  9. #define N 1011
  10. #define M 300001
  11. const int inf=2e9;
  12.  
  13. int n;
  14. int a[];
  15.  
  16. int max_len;
  17. int f[];
  18.  
  19. int tot=;
  20. int front[N],to[M<<],nxt[M<<],val[M<<],from[M<<];
  21.  
  22. int lev[N],num[N];
  23. int path[N];
  24. int cur[N];
  25.  
  26. int src,decc;
  27.  
  28. void read(int &x)
  29. {
  30. x=; char c=getchar();
  31. while(!isdigit(c)) c=getchar();
  32. while(isdigit(c)) { x=x*+c-''; c=getchar(); }
  33. }
  34.  
  35. void dp()
  36. {
  37. int mx;
  38. for(int i=n;i;--i)
  39. {
  40. mx=;
  41. for(int j=i+;j<=n;++j)
  42. if(a[j]>=a[i]) mx=max(mx,f[j]);
  43. f[i]=mx+;
  44. max_len=max(max_len,f[i]);
  45. }
  46. cout<<max_len;
  47. }
  48.  
  49. void add(int u,int v,int w)
  50. {
  51. to[++tot]=v; nxt[tot]=front[u]; front[u]=tot; val[tot]=w; from[tot]=u;
  52. to[++tot]=u; nxt[tot]=front[v]; front[v]=tot; val[tot]=; from[tot]=v;
  53. // cout<<u<<' '<<v<<' '<<w<<'\n';
  54. }
  55.  
  56. void build()
  57. {
  58. for(int i=;i<=n;++i) add(i<<,i<<|,);
  59. for(int i=;i<=n;++i)
  60. if(f[i]==max_len) add(src,i<<,);
  61. for(int i=;i<=n;++i)
  62. if(f[i]==) add(i<<|,decc,);
  63. for(int i=;i<=n;++i)
  64. for(int j=;j<i;++j)
  65. if(a[j]<=a[i] && f[i]==f[j]-) add(j<<|,i<<,);
  66. }
  67.  
  68. void rebuild()
  69. {
  70. tot=;
  71. memset(front,,sizeof(front));
  72.  
  73. add(<<,<<|,inf);
  74. add(n<<,n<<|,inf);
  75. for(int i=;i<n;++i) add(i<<,i<<|,);
  76.  
  77. if(f[]==max_len) add(src,<<,inf);
  78. if(f[n]==max_len) add(src,n<<,inf);
  79. for(int i=;i<n;++i)
  80. if(f[i]==max_len) add(src,i<<,);
  81.  
  82. if(f[]==) add(<<|,decc,inf);
  83. if(f[n]==) add(n<<|,decc,inf);
  84. for(int i=;i<n;++i)
  85. if(f[i]==) add(i<<|,decc,);
  86.  
  87. for(int i=;i<=n;++i)
  88. for(int j=;j<i;++j)
  89. if(a[j]<=a[i] && f[i]==f[j]-) add(j<<|,i<<,);
  90. }
  91.  
  92. bool bfs()
  93. {
  94. for(int i=src;i<=decc;++i) lev[i]=decc;
  95. queue<int>q;
  96. q.push(decc);
  97. lev[decc]=;
  98. int now,t;
  99. while(!q.empty())
  100. {
  101. now=q.front();
  102. q.pop();
  103. for(int i=front[now];i;i=nxt[i])
  104. {
  105. t=to[i];
  106. if(lev[t]==decc && val[i^])
  107. {
  108. lev[t]=lev[now]+;
  109. q.push(t);
  110. }
  111. }
  112. }
  113. return lev[src]!=decc;
  114. }
  115.  
  116. int augment()
  117. {
  118. int flow=inf,now=decc;
  119. int i;
  120. while(now!=src)
  121. {
  122. i=path[now];
  123. flow=min(flow,val[i]);
  124. now=from[i];
  125. }
  126. now=decc;
  127. while(now!=src)
  128. {
  129. i=path[now];
  130. val[i]-=flow;
  131. val[i^]+=flow;
  132. now=from[i];
  133. }
  134. return flow;
  135. }
  136.  
  137. void isap()
  138. {
  139. if(!bfs())
  140. {
  141. cout<<'\n'<<;
  142. return;
  143. }
  144. memset(num,,sizeof(num));
  145. for(int i=src;i<=decc;++i) num[lev[i]]++;
  146. int flow=;
  147. int now=src,t;
  148. while(lev[src]<decc)
  149. {
  150. if(now==decc)
  151. {
  152. flow+=augment();
  153. now=src;
  154. }
  155. bool advanced=false;
  156. for(int i=front[now];i;i=nxt[i])
  157. {
  158. t=to[i];
  159. if(lev[t]==lev[now]- && val[i])
  160. {
  161. advanced=true;
  162. path[t]=i;
  163. cur[now]=i;
  164. now=t;
  165. break;
  166. }
  167. }
  168. if(!advanced)
  169. {
  170. int mi=decc;
  171. for(int i=front[now];i;i=nxt[i])
  172. if(val[i]) mi=min(mi,lev[to[i]]);
  173. if(!num[--lev[now]]) break;
  174. num[lev[now]=mi+]++;
  175. cur[now]=front[now];
  176. if(now!=src) now=from[path[now]];
  177. }
  178. }
  179. cout<<'\n'<<flow;
  180. }
  181.  
  182. int main()
  183. {
  184. read(n);
  185. src=; decc=(n<<|)+;
  186. for(int i=;i<=n;++i) read(a[i]);
  187. dp();
  188. if(max_len==)
  189. {
  190. cout<<'\n'<<n<<'\n'<<n;
  191. return ;
  192. }
  193. build();
  194. isap();
  195. rebuild();
  196. isap();
  197. }

题目描述

«问题描述:

给定正整数序列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: 复制

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

  1. 2
  2. 2
  3. 3

说明

n\le 500n≤500

洛谷P2766 最长递增子序列问题的更多相关文章

  1. 洛谷 [p1439] 最长公共子序列 (NlogN)

    可以发现只有当两个序列中都没有重复元素时(1-n的排列)此种优化才是高效的,不然可能很不稳定. 求a[] 与b[]中的LCS 通过记录lis[i]表示a[i]在b[]中的位置,将LCS问题转化为最长上 ...

  2. 洛谷P3402 最长公共子序列

    题目背景 DJL为了避免成为一只咸鱼,来找Johann学习怎么求最长公共子序列. 题目描述 经过长时间的摸索和练习,DJL终于学会了怎么求LCS.Johann感觉DJL孺子可教,就给他布置了一个课后作 ...

  3. 洛谷P1439 最长公共子序列(LCS问题)

    题目描述 给出1-n的两个排列P1和P2,求它们的最长公共子序列. 输入输出格式 输入格式: 第一行是一个数n, 接下来两行,每行为n个数,为自然数1-n的一个排列. 输出格式: 一个数,即最长公共子 ...

  4. 洛谷P2766 最长不下降子序列问题(最大流)

    传送门 第一问直接$dp$解决,求出$len$ 然后用$f[i]$表示以$i$为结尾的最长不下降子序列长度,把每一个点拆成$A_i,B_i$两个点,然后从$A_i$向$B_i$连容量为$1$的边 然后 ...

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

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

  6. 洛谷 [P2766] 最长不下降子序列问题

    啊啊啊,再把MAXN和MAXM搞反我就退役 层次图求不相交路径数 第一问简单DP 第二问想办法把每一个不上升子序列转化成DAG上的一条路径,就转换成了求不相交路径数 因为每一个数只能用一次,所以要拆点 ...

  7. 洛谷P2766 最长不下降子序列问题 网络流_DP

    Code: #include<cstdio> #include<iostream> #include<vector> #include<algorithm&g ...

  8. (转载)最长递增子序列 O(NlogN)算法

    原博文:传送门 最长递增子序列(Longest Increasing Subsequence) 下面我们简记为 LIS. 定义d[k]:长度为k的上升子序列的最末元素,若有多个长度为k的上升子序列,则 ...

  9. 最长公共子序列(LCS)和最长递增子序列(LIS)的求解

    一.最长公共子序列 经典的动态规划问题,大概的陈述如下: 给定两个序列a1,a2,a3,a4,a5,a6......和b1,b2,b3,b4,b5,b6.......,要求这样的序列使得c同时是这两个 ...

随机推荐

  1. 福大软工1816 · 评分结果 · Alpha冲刺答辩总结

    作业地址:https://edu.cnblogs.com/campus/fzu/Grade2016SE/homework/2462 作业提交准则 按时交 - 有分 晚交 - 0分 迟交一周以上 - 倒 ...

  2. Java集合之HashSet/TreeSet原理

    Set集合 1.HashSet  只去重复, 没有顺序  HashSet的add方法会调用hashCode和equals, 所以存储在HashSet中的对象需要重写这两个方法. 2.TreeSet   ...

  3. 用windbg检查.NET线程池设置

    比如我们在machine.config中进行了这样的设置(8核CPU): <processModel maxWorkerThreads="100" maxIoThreads= ...

  4. 安恒杯2月月赛-应该不是xss

    1. 打开题目一看,是个留言板 2. 查看源码发现有几个js文件 依次打开发现在main.js里存在这样一段代码 3. 访问 /#login是登录的界面,/#chgpass是修改密码的界面,其中修改密 ...

  5. AJAX 跨域问题 php

    原生ajax请求方式: var xhr = new XMLHttpRequest(); xhr.open("POST", "http://xxxx.com/demo/b/ ...

  6. javascript中对象访问自身属性的方式

    在javascript中,通过对象的方法访问对象自身属性时,必须采用this.fieldName的方式. 原因是javascript中Function是无状态的,访问对象的属性时,必须指定当前的上下文 ...

  7. 在Asp.Net Core中使用Session

    1.在Stratup.cs中配置Session public void ConfigureServices(IServiceCollection services) { services.AddSes ...

  8. java 表单验证

    java 表单验证 1.思路:通过表单选择器,表单属性过滤器提取每个表单提交的值,进行验证 2.实现:javascript通过 onSubmit()事件,判断,返回值false不提交,返回true提交 ...

  9. The Dominator of Strings HDU - 6208(ac自动机板题)

    题意: 就是求是否有一个串 是其它所有串的母串 解析: 把所有的串都加入到trie数中  然后用最长的串去匹配就好了 emm..开始理解错题意了...看成了只要存在一个串是另一个的母串就好.. 然后输 ...

  10. MT【135】条件线性化

    已知\(x,y>0,\dfrac{1}{x}+\dfrac{2}{y}=1\),求\(\dfrac{1}{x+1}+\dfrac{2}{y+1}\)的最大值_____ 解答:令\(a=\dfra ...