LIS问题(DP解法)---poj1631
题目链接: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的更多相关文章
- 小明的密码-初级DP解法
#include #include #include using namespace std; int visited[5][20][9009];// 访问情况 int dp[5][20][9009] ...
- hdu_4352_XHXJ's LIS(数位DP+状态压缩)
题目连接:hdu_4352_XHXJ's LIS 题意:这题花大篇篇幅来介绍电子科大的一个传奇学姐,最后几句话才是题意,这题意思就是给你一个LL范围内的区间,问你在这个区间内最长递增子序列长度恰为K的 ...
- luogu5010 HMR的LIS III (dp+线段树)
这个东西和最长上升子序列很像 考虑如果已经知道每个位置为开头的LIS长度和个数 f[i],我可以扫一遍 判断这个个数和K的大小,找到第一个长度=len而且个数<K的,这个位置就是要选的 然后K- ...
- HDU 4352 XHXJ's LIS 数位dp lis
目录 题目链接 题解 代码 题目链接 HDU 4352 XHXJ's LIS 题解 对于lis求的过程 对一个数列,都可以用nlogn的方法来的到它的一个可行lis 对这个logn的方法求解lis时用 ...
- HDU.4352.XHXJ's LIS(数位DP 状压 LIS)
题目链接 \(Description\) 求\([l,r]\)中有多少个数,满足把这个数的每一位从高位到低位写下来,其LIS长度为\(k\). \(Solution\) 数位DP. 至于怎么求LIS, ...
- XHXJ's LIS(数位DP)
XHXJ's LIS http://acm.hdu.edu.cn/showproblem.php?pid=4352 Time Limit: 2000/1000 MS (Java/Others) ...
- 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 ...
- 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 ...
- (探讨贴)POJ 1463 树形DP解法的不正确性
POJ1463是一个典型的树状DP题. 通常解法如下代码所示: using namespace std; ; ]; int pre[maxn]; int childcnt[maxn]; int n; ...
随机推荐
- bzoj4153 [Ipsc2015]Familiar Couples
Description 有n对夫妇,一开始夫妇之间互不认识,若两男或两女成为朋友,称他们为"熟人","熟人"关系具有传递性,即若a熟b且b熟c则a熟c.若两组夫 ...
- 接口测试3-3Excel格式
java操作Excel,需要第三方库poi #xml <dependency> <groupId>org.apache.poi</groupId> <arti ...
- Immunity Debugger学习笔记
图1::Immunity主界面 注意事项:最下方的PyCommands窗格既可以执行调试命令也可以执行python脚步文件. 1.PyCommands学习 在 Immunity 中执行 Python ...
- 6.19-response(响应),session(会话技术,服务器端技术) 内置对象,application(内置对象),pageContext (内置对象),cookie(客户端技术)
一.response(响应) 页面重定向 response.sendRedirect(""); 转发: request.getRequestDispatcher("&qu ...
- 【BZOJ】4517 [Sdoi2016]排列计数(数学+错排公式)
题目 传送门:QWQ 分析 $ O(nlogn) $预处理出阶乘和阶乘的逆元,然后求组合数就成了$O(1)$了. 最后再套上错排公式:$ \huge d[i]=(i-1) \times (d[i-1] ...
- 安装HBase(0.9)数据库
基本知识: 1.hbase是一种基于列存储的数据库,也就是说它的一列的数据是存储在一个文件里面的,而传统的数据库存储都是一个文件存储多个行,这些行有不同的列,这些列的数据类型 不同. 2.基于HDFS ...
- java的缓存框架
1.java里面有一些开源的缓存框架,比如ecache,memcache,redis等缓存框架. 2.使用缓存框架的原理就是减少数据库端的压力,将缓存数据放在内存里面,存储成键值对的格式,这样可以不去 ...
- MySQL 创建数据库的两种方法
使用 mysqladmin 创建数据库 使用普通用户,你可能需要特定的权限来创建或者删除 MySQL 数据库. 所以我们这边使用root用户登录,root用户拥有最高权限,可以使用 mysql mys ...
- FBV和CBV区别
FBV和CBV区别 def dispatch(self, request, *args, **kwargs): # 做分发的 if request.meth ...
- LSTM(Long Short-Term Memory)长短期记忆网络
1. 摘要 对于RNN解决了之前信息保存的问题,例如,对于阅读一篇文章,RNN网络可以借助前面提到的信息对当前的词进行判断和理解,这是传统的网络是不能做到的.但是,对于RNN网络存在长期依赖问题,比如 ...