最长递增子序列-动态规划dp-(51nod 1134)(POJ 2533)

来源:互联网 发布:淘宝鹊桥报名入口 编辑:程序博客网 时间:2024/06/07 10:03

最长递增子序列粗解

带来了两个比较经典的求解最长递增子序列的题目

①点击打开链接 51nod 1134

1134最长递增子序列
基准时间限制:1 秒 空间限制:131072 KB 分值:0难度:基础题
给出长度为N的数组,找出这个数组的最长递增子序列。(递增子序列是指,子序列的元素是递增的)
例如:5 1 6 8 2 4 5 10,最长递增子序列是1 2 4 5 10。
Input
第1行:1个数N,N为序列的长度(2 <= N <= 50000)第2 - N + 1行:每行1个数,对应序列的元素(-10^9 <= S[i] <= 10^9)
Output
输出最长递增子序列的长度。
Input示例
8516824510
Output示例
5

最近在看动态规划  求解最长递增子序列有两种方法 一种是O(n^2) 一种是O(n^log(n))

对于这个题目只能用后者否则后几个例子会超时,但是这种办法只能求长度,求出来的顺序是不对的,贴上代码解释下。

#include<stdio.h>#include<iostream> #include <algorithm>#include<string.h>#include<math.h>#include<queue>#include<set>#define LL long long#define s(n) scanf("%d",&n)#define p(n) printf("%d",n)using namespace std;int N[50050];int dp[50050];int main(){int n;while(scanf("%d",&n)!=EOF){memset(dp,0,sizeof(dp));for(int i=1;i<=n;i++)scanf("%d",&N[i]);int top=1;dp[1]=N[1];for(int i=2;i<=n;i++){if(N[i]<dp[1])//找到一个最小的数字 dp[1]=N[i];else if(N[i]>dp[top])//找到当前一个最大的数 dp[++top]=N[i];else//介于最小和最大之间的数字 {int b=1,e=top;while(b<e){int mid=(b+e)/2;if(dp[mid]<=N[i])//如果中间值比那个值小的话 {b=mid+1;}elsee=mid;}dp[b]=N[i]; }}printf("%d\n",top);}return 0;} 
本方法就是不断更新对应位置的数字,比如   1 7 8 4 5 6

刚开始dp[1]=1 dp[2]=7 dp[3]=8 到了4的时候通过二分法找到了dp[2]>4 所以dp[2]=4,dp[3]=5,dp[4]=6; 通过这样的方式来更新,达到了二分 降低了复杂度。

②点击打开链接 POj2533

Longest Ordered Subsequence
Time Limit: 2000MS Memory Limit: 65536KTotal Submissions: 54723 Accepted: 24522

Description

A numeric sequence of ai is ordered if a1 < a2 < ... < aN. Let the subsequence of the given numeric sequence (a1a2, ..., aN) be any sequence (ai1ai2, ..., aiK), where 1 <= i1 < i2 < ... < iK <= N. For example, sequence (1, 7, 3, 5, 9, 4, 8) has ordered subsequences, e. g., (1, 7), (3, 4, 8) and many others. All longest ordered subsequences are of length 4, e. g., (1, 3, 5, 8).

Your program, when given the numeric sequence, must find the length of its longest ordered subsequence.

Input

The first line of input file contains the length of sequence N. The second line contains the elements of sequence - N integers in the range from 0 to 10000 each, separated by spaces. 1 <= N <= 1000

Output

Output file must contain a single integer - the length of the longest ordered subsequence of the given sequence.

Sample Input

71 7 3 5 9 4 8

Sample Output

4
也是求最长递增序列,没啥解释的,直接贴代码。

#include<stdio.h>#include<iostream> #include <algorithm>#include<string.h>#include<math.h>#include<queue>#include<set>#define LL long long#define s(n) scanf("%d",&n)#define p(n) printf("%d",n)using namespace std;int N[1050];int dp[1050];int main(){int n;while(scanf("%d",&n)!=EOF){memset(dp,0,sizeof(dp));for(int i=0;i<n;i++)scanf("%d",&N[i]);int maxx=1;dp[0]=1;for(int i=1;i<n;i++){dp[i]=1;for(int j=0;j<i;j++){if(N[j]<N[i] && dp[j]+1>dp[i]){dp[i]=dp[j]+1;maxx=max(maxx,dp[i]);}}}printf("%d\n",maxx);}return 0;} 
二层for循环 查找更新