题目描述 Description

给定正整数序列x1,..... , xn  。
(1)计算其最长递增子序列的长度s。
(2)计算从给定的序列中最多可取出多少个长度为s的递增子序列。
(3)如果允许在取出的序列中多次使用x1和xn,则从给定序列中最多可取出多少个长
度为s的递增子序列。

输入描述 Input Description

第1 行有1个正整数n,表示给定序列的长度。接
下来的1 行有n个正整数x1.....xn 。

输出描述 Output Description

第1 行是最长递增子序列的长度s。第2行是可取出的长度为s 的递增子序列个数。第3行是允许在取出的序列中多次使用x1和xn时可取出的长度为s 的递增子序列个数。

样例输入 Sample Input

4
3 6 2 5

样例输出 Sample Output

2
2
3

不得不吐槽codevs上面网络流24题好多数据都是很蛋疼的要输出方案又不给spj……鬼知道你数据是用哪种方案啊

啊这题还算正常

第一问LIS随便求

第二问拆点完S向所有x1连流量1费用0的边,所有x2向T连流量1费用0的边,所有x1向x2连流量1费用1的边。因为要表示有没有取这个点

对于所有a[i]<a[j]且i<j的,i2向j1连流量1费用0的边

然后跑最大费用。每次增广搞完如果答案是第一问的最长长度,那么ans++。

第三问就是第二问的建图与1和n有关的边的流量全改inf就对了

#include<cstdio>
#include<iostream>
#include<cstring>
#define LL long long
#define inf 0x3ffffff
#define S 0
#define T 1001
using namespace std;
inline LL read()
{
LL x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int n,ans,flow,cnt,tot;
int a[510];
int mn[510];
struct edge{int from,to,next,v,c;}e[500010];
int head[1010],dis[1010],q[1010],from[1010];
bool mrk[1010];
inline void ins(int u,int v,int w,int c)
{
e[++cnt].to=v;
e[cnt].v=w;
e[cnt].c=c;
e[cnt].from=u;
e[cnt].next=head[u];
head[u]=cnt;
}
inline void insert(int u,int v,int w,int c)
{
ins(u,v,w,c);
ins(v,u,0,-c);
}
inline int bsearch(int x)
{
int l=1,r=ans,s=0;
while(l<=r)
{
int mid=(l+r)>>1l;
if (mn[mid]<=x){s=mid;l=mid+1;}
else r=mid-1;
}
return s;
}
inline bool spfa()
{
for (int i=1;i<=T;i++)dis[i]=inf;
memset(mrk,0,sizeof(mrk));
int t=0,w=1;
dis[S]=0;q[0]=S;mrk[S]=1;
while (t!=w)
{
int now=q[t++];if (t==1005)t=0;
for (int i=head[now];i;i=e[i].next)
if (e[i].v&&dis[now]+e[i].c<dis[e[i].to])
{
dis[e[i].to]=dis[now]+e[i].c;
from[e[i].to]=i;
if (!mrk[e[i].to])
{
mrk[e[i].to]=1;
q[w++]=e[i].to;
if (w==1005)w=0;
}
}
mrk[now]=0;
}
if (dis[T]==inf)return 0;
return 1;
}
inline void mcf()
{
int x=inf;flow=0;
for (int i=from[T];i;i=from[e[i].from])
x=min(x,e[i].v);
for (int i=from[T];i;i=from[e[i].from])
{
e[i].v-=x;
e[i^1].v+=x;
flow+=x*e[i].c;
}
if (flow==-ans)tot++;
}
int main()
{
n=read();
for (int i=1;i<=n;i++)a[i]=read();
ans=1;mn[1]=a[1];
for (int i=2;i<=n;i++)
{
int fnd=bsearch(a[i]);
if (fnd==ans)mn[++ans]=a[i];
else mn[fnd+1]=a[i];
}
printf("%d\n",ans);
cnt=1;
for(int i=1;i<=n;i++)
{
insert(S,i,1,0);
insert(i+n,T,1,0);
insert(i,i+n,1,-1);
}
for (int i=1;i<=n;i++)
for (int j=i+1;j<=n;j++)
if (a[i]<=a[j])insert(i+n,j,1,0);
while (spfa())mcf();
printf("%d\n",tot);
memset(head,0,sizeof(head));
cnt=1;tot=0;
insert(S,1,inf,0);insert(S,n,inf,0);
insert(1+n,T,inf,0);insert(2*n,T,inf,0);
insert(1,1+n,inf,-1);insert(n,2*n,inf,-1);
for(int i=1;i<=n;i++)
{
insert(S,i,1,0);
insert(i+n,T,1,0);
insert(i,i+n,1,-1);
}
for (int i=1;i<n;i++)
for (int j=i+1;j<=n;j++)
if (a[i]<=a[j])
if (i!=1&&j!=n)insert(i+n,j,1,0);
else insert(i+n,j,inf,0);
while (spfa())mcf();
printf("%d\n",tot);
}

 

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

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

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

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

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

  3. 最长递增子序列 O(NlogN)算法

    转自:点击打开链接 最长递增子序列,Longest Increasing Subsequence 下面我们简记为 LIS. 排序+LCS算法 以及 DP算法就忽略了,这两个太容易理解了. 假设存在一个 ...

  4. 51nod 1134 最长递增子序列

    题目链接:51nod 1134 最长递增子序列 #include<cstdio> #include<cstring> #include<algorithm> usi ...

  5. 动态规划 - 最长递增子序列(LIS)

    最长递增子序列是动态规划中经典的问题,详细如下: 在一个已知的序列{a1,a2,...,an}中,取出若干数组组成新的序列{ai1,ai2,...,aim},其中下标i1,i2,...,im保持递增, ...

  6. 最长递增子序列问题 nyoj 17单调递增最长子序列 nyoj 79拦截导弹

    一,    最长递增子序列问题的描述 设L=<a1,a2,…,an>是n个不同的实数的序列,L的递增子序列是这样一个子序列Lin=<aK1,ak2,…,akm>,其中k1< ...

  7. 2.16 最长递增子序列 LIS

    [本文链接] http://www.cnblogs.com/hellogiser/p/dp-of-LIS.html [分析] 思路一:设序列为A,对序列进行排序后得到B,那么A的最长递增子序列LIS就 ...

  8. 【动态规划】拦截导弹_dilworth定理_最长递增子序列

    问题 K: [动态规划]拦截导弹 时间限制: 1 Sec  内存限制: 256 MB提交: 39  解决: 10[提交][状态][讨论版] 题目描述 张琪曼:“老师,修罗场是什么?” 墨老师:“修罗是 ...

  9. COGS731 [网络流24题] 最长递增子序列(最大流)

    给定正整数序列x1,..., xn (n<=500).(1)计算其最长递增子序列的长度s.(2)计算从给定的序列中最多可取出多少个长度为s的递增子序列.(3)如果允许在取出的序列中多次使用x1和 ...

随机推荐

  1. [转] stat命令输出结果中, Access,Modify,Change的含义

    先建立一个空白文件a.txt 1 [emduser@emd tmp]$ touch a.txt 2   3 [emduser@emd tmp]$ ls -al a.txt 4   5 -rw-rw-r ...

  2. Asp.Net mvc筛选器中返回信息中断操作

    在mvc中,使用response.end()或Response.Redirect("url"); 是无法阻止请求继续往下执行的.如果在action中,可以我们可以使用return ...

  3. Java基础知识强化72:正则表达式之判断功能(手机号码判断 和 校验邮箱)

    1.  判断功能: 使用了String类的matches方法,如下: public boolean matches(String regex): 2. 判断手机号码的案例: package cn.it ...

  4. 安装android studio 出现的路径问题 tools.jar' seems to be not in Android Studio classpath

    尝试一下android studio  ,谁知出现路径问题 'tools.jar' seems to be not in Android Studio classpath. Please ensure ...

  5. 【网络流#7】POJ 3281 Dining 最大流 - 《挑战程序设计竞赛》例题

    不使用二分图匹配,使用最大流即可,设源点S与汇点T,S->食物->牛->牛->饮料->T,每条边流量为1,因为流过牛的最大流量是1,所以将牛拆成两个点. 前向星,Dini ...

  6. SpringMVC05使用注解的方式

    <body> <a href="add">新增</a> <a href="update">修改</a> ...

  7. svg学习笔记

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  8. lucene实战(第二版)学习笔记

    初识Lucene 构建索引 为应用程序添加搜索功能 Lucene的分析过程

  9. MySQL导入导出命令

    前言 如果使用图形化界面,那么可以通过几个点击即可导入.导出.本文是假定你没有安装那些如Navicat等GUI管理软件. 场景 假设在电脑A和电脑B中都装有MySQL数据库管理系统,并且在电脑A的My ...

  10. [转]MySQL数据库的热备份

    一.系统环境描述:      1.两台数据库服务器,A和B:      2.当前A正在使用,将作为主服务器,B为准备用来做备用数据库服务器:      3.要进行热备份的数据库中含有类型为MyISAM ...