最长递增子序列——解题报告

最长递增子序列——解题报告

题目描述:给定一个数组,长度为n,求出其中最长递增子序列。

分析:这题可以用动态规划求解,遍历i = 1 : n,当第i个数比前面j数大,而且前面的子序列长度加1之后,比现在的第i个子序列长的话,那么就变换。额,晦涩难懂额。。看代码可以好一些。

代码如下:

#include<iostream>
using namespace std; 

// solution 1: dp
int maxSubLength(int a[], int n)
{
	int *LIS = new int[n];
	int maxLIS = INT_MIN;
	for(int i = 0; i < n; i++)  // 遍历i
	{
		LIS[i] = 1;
		for(int j = 1; j < i; j++)  // 遍历j,范围是1~i
		{
			if(a[j] < a[i] && LIS[j] + 1 > LIS[i])  // 核心部分
				LIS[i] = LIS[j] + 1;
			maxLIS = maxLIS > LIS[i] ? maxLIS : LIS[i];
		}
	}
	return maxLIS;
}

int main()
{
	int a[] = {1, -1, 2, -3, 4, -5, 6, -7}; 

	// dp algorithm
	cout<<maxSubLength(a, 8)<<endl; 

	return 0;
}
时间: 2024-10-10 05:31:44

最长递增子序列——解题报告的相关文章

BZOJ 3173 [Tjoi2013] 最长上升子序列 解题报告

这个题感觉比较简单,但却比较容易想残.. 我不会用树状数组求这个原排列,于是我只好用线段树...毕竟 Gromah 果弱马. 我们可以直接依次求出原排列的元素,每次找到最小并且最靠右的那个元素,假设这是第 $i$ 次找的,那么这就是原排列的第 $i$ 项,然后我们就把这个元素删去(变成很大的数),再把这个数以左的数都加 1,进行下一轮. 然后就是裸的最长上升子序列啦~~~ 时间复杂度 $O(n\log n)$,空间复杂度 $O(n)$. 1 #include <cstdio> 2 #inclu

最长上升子序列解题报告

动规方程f[i]=f[j]+1(1<=j<i, a[j]<a[i]) 教训最长上升子序列有一个特点,就是答案最小都是1,所以可以给f[i]赋值为1,还有一种处理方式是并不赋值为1,但是在输出答案的时候加1就好了(其实就是偏移量).给每个f[i]加1其实就意味着每个数都可能是最长上升子序列的第一个元素. 然后我犯了一个错误,只给f[1]赋值为1,其实在算法上就意味着默认最长上升子序列是从第一个数开始,呃,错的.然后自己给数据就往往给的是从第一开始的答案,总是wrong.

最长公共子序列解题报告

if(x[i]==y[j]) f[i][j]=f[i-1][j-1]+1; else if(x[i]!=y[j]) f[i][j]=max(f[i-1][j], f[i][j-1]); 原决策 这一块其实动规方程是 f[i][j]=max(f[i-1][j-1]+(x[i]==y[j]), f[i][j-1], f[i-1][j]); 动规方程 可以联系到射箭一题 1 #include <stdio.h> 2 #define maxn 501 3 int x[maxn], y[maxn], f

动态规划(DP),最长递增子序列(LIS)

题目链接:http://poj.org/problem?id=2533 解题报告: 状态转移方程: dp[i]表示以a[i]为结尾的LIS长度 状态转移方程: dp[0]=1; dp[i]=max(dp[k])+1,(k<i),(a[k]<a[i]) #include <stdio.h> #define MAX 1005 int a[MAX];///存数据 int dp[MAX];///dp[i]表示以a[i]为结尾的最长递增子序列(LIS)的长度 int main() { int

HDU 3998 Sequence (最长递增子序列+最大流SAP,拆点法)经典

Sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1666    Accepted Submission(s): 614 Problem Description There is a sequence X (i.e. x[1], x[2], ..., x[n]). We define increasing subsequ

算法总结之 最长递增子序列

给定一个数组arr,返回arr最长递增子序列 要求 如果长度为N 请实现时间复杂度为O(N logN)的方法 动态规划解题思路: 1 生成长度为N的数组dp, dp[i]表示在以arr[i]这个数结尾的情况下,arr[0....i]中的最大递增子序列长度 2 对第一个数arr[0]来说,令dp[0]=1,接下来从左到右依次算出每个位置的数结尾情况下,最长递增子序列长度

笔试算法题(35):最长递增子序列 &amp; 判定一个字符串是否可由另一个字符串旋转得到

出题:求数组中最长递增子序列的长度(递增子序列的元素可以不相连): 分析: 解法1:应用DP之前需要确定当前问题是否具有无后效性,也就是每个状态都是对之前状态的一个总结,之后的状态仅会受到前一个状态的影响:对于递增子序列 而言,可以首先确定前面k个元素的最长子序列,然后计算增加一个元素之后的最长子序列.由于每个位置i都会与0-i的每个位置之前的LIS进行比较,并选 择保持递增的一个序列,所以总能找到LIS,但是时间复杂度为O(N^2),空间复杂度为O(N): 此解法的性能的瓶颈在于对于位置为i+

[ACM] 九度OJ 合唱队形 (最长递增子序列改版)

题目1131:合唱队形 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:1680 解决:520 题目描述: N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学不交换位置就能排成合唱队形. 合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1, 2, -, K,他们的身高分别为T1, T2, -, TK, 则他们的身高满足T1 < T2 < - < Ti , Ti > Ti+1 > - > TK (1 <= i <=

【动态规划】拦截导弹_dilworth定理_最长递增子序列

问题 K: [动态规划]拦截导弹 时间限制: 1 Sec  内存限制: 256 MB提交: 39  解决: 10[提交][状态][讨论版] 题目描述 张琪曼:“老师,修罗场是什么?” 墨老师:“修罗是佛家用语,修罗毕生以战斗为目标,修罗场指的是他们之间的死斗坑,人们通常用‘修罗场’来形容惨烈的战场.后来又引申出‘一个人在困境中做绝死奋斗’的意思.所以,这其实也在暗示我们,即使是身处绝境,也不要放弃奋斗.再说了,情况其实没有这么糟糕,因为我们最新的导弹拦截系统已经研制好了.” 魔法世界为了防御修罗