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

最长递增子序列粗解

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

点击打开链接 51nod 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示例
8
5
1
6
8
2
4
5
10
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;
					}
					else
						e=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: 65536K
Total 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

7
1 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循环 查找更新




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值