题目链接:http://poj.org/problem?id=1631

这个题题目有些难看懂hhh,但实质就是求LIS--longest increasing sequence。

以下介绍LIS的解法模板:

一.O(n^2)解法

用a数组存储数据,f[i]表示以a[i] 结尾的最长子序列的长度,这样max(f[i])就是所求结果。

代码如下:

 #include<cstdio>
#include<algorithm>
using namespace std; int n,p;
int a[],f[];
int res; int main(){
scanf("%d",&n);
while(n--){
res=;
scanf("%d",&p);
for(int i=;i<=p;i++)
scanf("%d",&a[i]),f[i]=;
for(int i=;i<=p;i++)
for(int j=;j<i;j++)
if(a[j]<a[i]){
f[i]=max(f[i],f[j]+);
if(f[i]>res) res=f[i];
}
printf("%d\n",res);
}
return ;
}

但是算法复杂度为n2,题目p为4e4,还是多组询问,明显会超时。

二 . O(nlogn)解法

假设数字序列为a[N](也可不用保存,一边读入一边处理),我们会用到一个数组f[N],f[k]保存的是数组a中所有长为k的不下降子序列最后一个元素的最小值(下面将简称为最小最后元素),显然f的长度len即为所求。而且容易用反证法证明这个数组是递增的,若存在i<j,且f[i]>f[j],可以这样想,既然存在一个长为j的且最后一个元素为f[j]的不下降子串,则必然存在一个长为i(i<j)且最后一个元素为f[j]的不下降子串,所以f[i]<=f[j],与假设矛盾。初始化的时候,f中只有一个元素,即数字序列的第一个元素,显然f[1]=a[1],接着,每次读入一个数字时,相当数组a新增一个元素,我们设为tmp,我们的任务就是维持f数组的定义,具体操作如下:若tmp>f[len],则f[++len]=tmp,这个容易理解,若tmp<=f[1],则f[1]=tmp,这两种情况都容易理解,关键在于tmp>f[1]&&tmp<=f[len],这时需将f数组中第一个(从1到len)大于tmp的数字更新为tmp(这么做的原因是为了使后面输入时形成更长的上升子序列,不理解的话可以举个例子好好想想),因为f是有序的,所以可以使用二分查找,然后更新。当a数组确定后(数据读入完成),数组f也就确定了,此时数组f的长度就是数组a中以第一个数开头的最长不下降子序列的长度。读入数据使用一层循环,查找更新需一层循环,由于查找时用了二分,所以总的时间复杂度为O(nlogn)。至此算法就结束了。

AC代码如下:

#include<cstdio>
#include<algorithm>
using namespace std; int n,p;
int f[];
int len; int main(){
scanf("%d",&n);
while(n--){
len=;
scanf("%d",&p);
int tmp;
scanf("%d",&tmp);
f[++len]=tmp;
p--;
while(p--){
scanf("%d",&tmp);
if(tmp>f[len]) f[++len]=tmp;
else if(tmp<=f[]) f[]=tmp;
else{
int l=,r=len,m;
while(l<=r){
m=(l+r)/;
if(f[m]>=tmp) r=m-1;else l=m+;
}
f[l]=tmp;
}
}
printf("%d\n",len);
}
return ;
}

这个是求最长上升子序列。

求最长不下降子序列的代码如下:

#include<cstdio>
#include<algorithm>
using namespace std; int n,p;
int f[];
int len; int main(){
scanf("%d",&n);
while(n--){
len=;
scanf("%d",&p);
int tmp;
scanf("%d",&tmp);
f[++len]=tmp;
p--;
while(p--){
scanf("%d",&tmp);
if(tmp>=f[len]) f[++len]=tmp;
else if(tmp<f[]) f[]=tmp;
else{
int l=,r=len,m;
while(l<=r){
m=(l+r)/;
if(f[m]>tmp) r=m-;
else l=m+;
}
f[l]=tmp;
}
}
printf("%d\n",len);
}
return ;
}

LIS问题(DP解法)---poj1631的更多相关文章

  1. 小明的密码-初级DP解法

    #include #include #include using namespace std; int visited[5][20][9009];// 访问情况 int dp[5][20][9009] ...

  2. hdu_4352_XHXJ's LIS(数位DP+状态压缩)

    题目连接:hdu_4352_XHXJ's LIS 题意:这题花大篇篇幅来介绍电子科大的一个传奇学姐,最后几句话才是题意,这题意思就是给你一个LL范围内的区间,问你在这个区间内最长递增子序列长度恰为K的 ...

  3. luogu5010 HMR的LIS III (dp+线段树)

    这个东西和最长上升子序列很像 考虑如果已经知道每个位置为开头的LIS长度和个数 f[i],我可以扫一遍 判断这个个数和K的大小,找到第一个长度=len而且个数<K的,这个位置就是要选的 然后K- ...

  4. HDU 4352 XHXJ's LIS 数位dp lis

    目录 题目链接 题解 代码 题目链接 HDU 4352 XHXJ's LIS 题解 对于lis求的过程 对一个数列,都可以用nlogn的方法来的到它的一个可行lis 对这个logn的方法求解lis时用 ...

  5. HDU.4352.XHXJ's LIS(数位DP 状压 LIS)

    题目链接 \(Description\) 求\([l,r]\)中有多少个数,满足把这个数的每一位从高位到低位写下来,其LIS长度为\(k\). \(Solution\) 数位DP. 至于怎么求LIS, ...

  6. XHXJ's LIS(数位DP)

    XHXJ's LIS http://acm.hdu.edu.cn/showproblem.php?pid=4352 Time Limit: 2000/1000 MS (Java/Others)     ...

  7. HDU 4352 - XHXJ's LIS - [数位DP][LIS问题]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4352 Time Limit: 2000/1000 MS (Java/Others) Memory Li ...

  8. hdu 4352 XHXJ's LIS 数位dp+状态压缩

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4352 XHXJ's LIS Time Limit: 2000/1000 MS (Java/Others ...

  9. (探讨贴)POJ 1463 树形DP解法的不正确性

    POJ1463是一个典型的树状DP题. 通常解法如下代码所示: using namespace std; ; ]; int pre[maxn]; int childcnt[maxn]; int n; ...

随机推荐

  1. ES之七:配置文件详解

    安装流程 http://www.elasticsearch.org/overview/elkdownloads/下载对应系统的安装包(我下载的是tar的),下载解压以后运行es根目录下bin目录的el ...

  2. MariaDB管理系统

    MariaDB管理系统 [root@c4kaichen@163 ~]# yum install mariadb[root@c4kaichen@163 ~]# yum install -y mariad ...

  3. [UE4]封装、继承、多态

    面向对象编程的三大特征 一.封装 公开能做什么,隐藏如何做.封装的目的是减少类之间的依赖. 二.继承 让一个类拥有另一个类的状态和行为,前者可以不加修改地完全复用后者的实现,也可以对有些行为做出自己的 ...

  4. SVN - 简单使用手册

    背景 由于项目需要,新增了两名程序员来一起支持一个分支的开发工作,因此需要在原来的SVN中制作分支并且为new commer  分配用户以及权限. 0. 准备 在Window系统上使用SVN,我们最好 ...

  5. php如何高效的读取大文件

    通常来说在php读取大文件的时候,我们采用的方法一般是一行行来讲取,而不是一次性把文件全部写入内存中,这样会导致php程序卡死,下面就给大家介绍这样一个例子. 需求:有一个800M的日志文件,大约有5 ...

  6. Spark分析之SparkContext启动过程分析

    SparkContext作为整个Spark的入口,不管是spark.sparkstreaming.spark sql都需要首先创建一个SparkContext对象,然后基于这个SparkContext ...

  7. Python中属性和描述符的简单使用

    Python的描述符和属性是接触到Python核心编程中一个比较难以理解的内容,自己在学习的过程中也遇到过很多的疑惑,通过google和阅读源码,现将自己的理解和心得记录下来,也为正在为了该问题苦恼的 ...

  8. CentOS重新加载网卡报错 Active connection path: /org/freedesktop/NetworkManager/ActiveConnection/

    重新加载网卡时出现的错误如下: 1 [root@vdb1 dev]# service network restart 2 Shutting down interface eth0: Device st ...

  9. js中的数组操作

    <!DOCTYPE HTML> <html > <head> <meta http-equiv="Content-Type" conten ...

  10. selenium+python自动化91-unittest多线程生成报告(BeautifulReport)

    前言 selenium多线程跑用例,这个前面一篇已经解决了,如何生成一个测试报告这个是难点,刚好在github上有个大神分享了BeautifulReport,完美的结合起来,就能生成报告了. 环境必备 ...