题目描述 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. 了解SVG

    页的节点类型,我们将说明怎样通过Illustrator高速的把SVG文档加入到网页中.我们还会讲讲D3.js,一个强大的.SVG控制的JavaScript库. "SVG并不仅仅用于像素处理. ...

  2. [Unit Testing] Angular Test component with required

    export default (ngModule) => { describe('Table Item component', () => { let $compile, directiv ...

  3. iOS 在 Xcode 中重命名项目名称

    本教程使用的 Xcode 版本是Xcode 6.3.1,网上有好多的教程,都是在 Xcode 4 上做的讲解,现以本文章讲解一下如何在 Xcode 6.3.1 中重命名你的项目名称,包括你的应用名称. ...

  4. Android BroadcastReceiver实例Demo(有序广播的发送)

    上一篇简介了广播的发送,这篇主要介绍下,有序广播的发送. 设置完相关属性的时候,广播就会依照有序的方式进行发送: 发送顺序: 先发送第二条广播: 再发送第一条广播: 最后发送第三条广播. 代码例如以下 ...

  5. struts2,hibernate,spring整合笔记(4)--struts与spring的整合

    饭要一口一口吃,程序也要一步一步写, 很多看起来很复杂的东西最初都是很简单的 下面要整合struts和spring spring就是我们的管家,原来我们费事费神的问题统统扔给她就好了 先写一个测试方法 ...

  6. C++输出hello world 详细注释

    /* #include<iostream> #:预处理标志,后面跟预处理指令,include:预处理指令,包含 <iostream>:c++头文件,输入输出流 这行的作用就是在 ...

  7. Eclipse利用代理快速安装插件

    在eclipse启动时增加以下参数: eclipse.exe -vmargs -DproxySet=true -DproxyHost=aProxyAddress -DproxyPort=aProxyP ...

  8. Installing node-oracledb on Microsoft Windows

    版本 7 由 Laura Ramsey-Oracle 于 2015-10-19 下午11:46创建,最后由 cj 于 2015-10-22 下午7:44修改. Installing node-orac ...

  9. chrome Provisional headers are shown错误提示

    1.一般出现这个错误是请求没有发送成功 可能原因:在上传文件或ajax上传时指定的timeout,过时时间小 其他资料: http://www.duanzhihe.com/575.html http: ...

  10. html5之web worker

    Web Worker   在本文中 与 Web Worker 进行双向通信 WindowTimers 在 IE10 Platform Preview 4 中对 Web Worker 的更新 API 参 ...