最长递增子序列(cogs 731)
«问题描述:
给定正整数序列x1,..., xn。
(1)计算其最长递增子序列的长度s。
(2)计算从给定的序列中最多可取出多少个长度为s的递增子序列。
(3)如果允许在取出的序列中多次使用x1和xn,则从给定序列中最多可取出多少个长度为s的递增子序列。
注意:这里的最长递增子序列即最长不下降子序列!!!
«编程任务:
设计有效算法完成(1)(2)(3)提出的计算任务。
«数据输入:
由文件alis.in提供输入数据。文件第1 行有1个正整数n(n<=500),表示给定序列的长度。接
下来的1 行有n个正整数x1,..., xn。
«结果输出:
程序运行结束时,将任务(1)(2)(3)的解答输出到文件alis.out中。第1 行是最长
递增子序列的长度s。第2行是可取出的长度为s 的递增子序列个数。第3行是允许在取出
的序列中多次使用x1和xn时可取出的长度为s 的递增子序列个数。
输入文件示例 输出文件示例
alis.in
4
3 6 2 5
alis.out
2
2
3
/*
第一问很好求,第二问网络流貌似可做(废话),但是想了很久,没想出怎么建图,看了题解才发现自己太弱了。
完全可以按照但都是求出的f数组的顺序建边,对于第三问,建图的时候将容量设为无限大就好了。
*/
#include<cstdio>
#include<iostream>
#include<queue>
#include<cstring>
#define N 1010
#define M 1000010
#define inf 1000000000
using namespace std;
int a[N],f[N],S,T,ans,n;
int head[N],dis[N],cnt;
struct node{int v,pre,f;}e[M];
int dp(){
f[]=;int maxn=;
for(int i=;i<=n;i++){
int p=;
for(int j=i;j>=;j--)
if(a[j]<=a[i]) p=max(p,f[j]);
f[i]=p+;
maxn=max(maxn,f[i]);
}
return maxn;
}
void add(int u,int v,int f){
e[++cnt].v=v;e[cnt].f=f;e[cnt].pre=head[u];head[u]=cnt;
e[++cnt].v=u;e[cnt].f=;e[cnt].pre=head[v];head[v]=cnt;
}
void build1(){
cnt=;memset(head,,sizeof(head));
for(int i=;i<=n;i++){
if(f[i]==) add(S,i,);
add(i,i+n,);
if(f[i]==ans) add(i+n,T,);
for(int j=;j<i;j++)
if(a[j]<=a[i]&&f[j]+==f[i])
add(j+n,i,);
}
}
void build2(){
cnt=;memset(head,,sizeof(head));
for(int i=;i<=n;i++){
if(i==||i==n){
if(f[i]==) add(S,i,inf);
add(i,i+n,inf);
if(f[i]==ans) add(i+n,T,inf);
}
else {
if(f[i]==) add(S,i,);
add(i,i+n,);
if(f[i]==ans) add(i+n,T,);
}
for(int j=;j<i;j++)
if(a[j]<=a[i]&&f[j]+==f[i])
add(j+n,i,);
}
}
bool bfs(){
memset(dis,-,sizeof(dis));
queue<int> q;q.push(S);dis[S]=;
while(!q.empty()){
int u=q.front();q.pop();
for(int i=head[u];i;i=e[i].pre)
if(e[i].f&&dis[e[i].v]==-){
dis[e[i].v]=dis[u]+;
q.push(e[i].v);
if(e[i].v==T) return true;
}
}
return dis[T]!=-;
}
int dinic(int x,int f){
int rest=f;
if(x==T) return f;
for(int i=head[x];i;i=e[i].pre)
if(dis[e[i].v]==dis[x]+&&e[i].f){
int t=dinic(e[i].v,min(rest,e[i].f));
if(!t) dis[e[i].v]=-;
rest-=t;
e[i].f-=t;
e[i^].f+=t;
}
return f-rest;
}
int main(){
scanf("%d",&n);S=;T=n*+;
for(int i=;i<=n;i++) scanf("%d",&a[i]);
ans=dp();printf("%d\n",ans);
if(ans==) {printf("%d\n%d",n,n);return ;}
build1();int maxflow=;
while(bfs()) maxflow+=dinic(S,inf);
printf("%d\n",maxflow);
build2();maxflow=;
while(bfs()) maxflow+=dinic(S,inf);
printf("%d",maxflow);
return ;
}
最长递增子序列(cogs 731)的更多相关文章
- Cogs 731. [网络流24题] 最长递增子序列(最大流)
[网络流24题] 最长递增子序列 ★★★☆ 输入文件:alis.in 输出文件:alis.out 简单对比 时间限制:1 s 内存限制:128 MB «问题描述: 给定正整数序列x1,-, xn. ( ...
- (转载)最长递增子序列 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同时是这两个 ...
- 最长递增子序列 O(NlogN)算法
转自:点击打开链接 最长递增子序列,Longest Increasing Subsequence 下面我们简记为 LIS. 排序+LCS算法 以及 DP算法就忽略了,这两个太容易理解了. 假设存在一个 ...
- 51nod 1134 最长递增子序列
题目链接:51nod 1134 最长递增子序列 #include<cstdio> #include<cstring> #include<algorithm> usi ...
- 动态规划 - 最长递增子序列(LIS)
最长递增子序列是动态规划中经典的问题,详细如下: 在一个已知的序列{a1,a2,...,an}中,取出若干数组组成新的序列{ai1,ai2,...,aim},其中下标i1,i2,...,im保持递增, ...
- 最长递增子序列问题 nyoj 17单调递增最长子序列 nyoj 79拦截导弹
一, 最长递增子序列问题的描述 设L=<a1,a2,…,an>是n个不同的实数的序列,L的递增子序列是这样一个子序列Lin=<aK1,ak2,…,akm>,其中k1< ...
- 2.16 最长递增子序列 LIS
[本文链接] http://www.cnblogs.com/hellogiser/p/dp-of-LIS.html [分析] 思路一:设序列为A,对序列进行排序后得到B,那么A的最长递增子序列LIS就 ...
- 【动态规划】拦截导弹_dilworth定理_最长递增子序列
问题 K: [动态规划]拦截导弹 时间限制: 1 Sec 内存限制: 256 MB提交: 39 解决: 10[提交][状态][讨论版] 题目描述 张琪曼:“老师,修罗场是什么?” 墨老师:“修罗是 ...
随机推荐
- java中的堆与栈
Java 中的堆和栈 Java把内存划分成两种:一种是栈内存,一种是堆内存. 在函数中定义的一些基本类型的变量和对象的引用变量都在函数的栈内存中分配 . 当在一段代码块定义一个变量时,Java就在栈中 ...
- 如何启动Intel VT-x
如何启动Intel VT-x 5 在64bit win7系统下安装了Vmware10,然后安装64位的UbuntuKylin 14.04,想要打开UbuntuKylin,弹出如下对话框: 请问该如何启 ...
- JS中的delete操作符
首先,delete删除成功返回true,失败返回false. js代码: function wxCount ($element) { this.init($element); } wxCount.pr ...
- js 返回上一页并刷新页面
js 方法 代码如下 self.location=document.referrer;
- js的正则表达式总结
1.8-20位数字 or 字母 or 特殊字符 var reg = /^[0-9a-zA-Z!@#$%^&*()_+-/.]{8,20}$/; 2.8-20位 数字+字母+特殊字符 //正则 ...
- java在线聊天项目0.2版本 制作客户端窗体,使用swing(用户界面开发工具包)和awt(抽象窗口工具包) BorderLayout布局与GridLayout布局不同之处 JPanel设置大小
代码如下: package com.swift; import java.awt.BorderLayout; import java.awt.Color; import javax.swing.JBu ...
- UIScreen, UIWindow
模仿书上或网上的例子,每次最开始就是 在 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: ...
- html中注释的问题
在修改jsp页面的时候遇到了一个有点难懂的注释,mark一下 <script> <!-- alert("js code"); //--> </scri ...
- 【dp】淘宝的推荐系统
可能最近做二分和DFS做傻了? 小明刚刚入职淘宝,老大给他交代了一个简单的任务,实现一个简易的商品推荐系统. 这个商品推荐系统的需求如下: 一共有 n 件商品可以被推荐,他们的编号分别为 1 到 n. ...
- python 实现计算器功能 输入字符串,输出相应结果
import re formul='1 - 2 *( (6 0- 30+(0-40/5) * (9-2* 5/3 +7 /3*99/4*2998 +10 *568/14)) - (-4*3) / (1 ...