华为OJ--Redraiment的走法--寻找最大递增子序列

题目:

题目 Redraiment的走法
题目描述 Redraiment是走梅花桩的高手。Redraiment总是起点不限,从前到后,往高的桩子走,但走的步数最多,不知道为什么?你能替Redraiment研究他最多走的步数吗?
样例输入 6
2 5 1 5 4 5
样例输出 3
提示 Example:
6个点的高度各为 2 5 1 5 4 5
如从第1格开始走,最多为3步, 2 4 5
从第2格开始走,最多只有1步,5
而从第3格开始走最多有3步,1 4 5
从第5格开始走最多有2步,4 5
所以这个结果是3。
接口说明 方法原型:
int GetResult(int num, int[] pInput, List pResult);
输入参数 int num:整数,表示数组元素的个数(保证有效)。
int[] pInput: 数组,存放输入的数字。
输出参数 List pResult: 保证传入一个空的List,要求把结果放入第一个位置。
返回值 正确返回1,错误返回0

思想:本题就是一个求解最大的递增子序列即可!
例如:我们现在给定一个长度为5的数组list:[4, 5, 1, 3, 6],那么最大的递增数组则是:[1, 3, 6]或者[4, 5, 6],长度是3.
则我们该题目我们可以利用动态规划的思想来写,设置一个dp[i]是记录上面数组list[i]为末尾元素的最长递增子序列。
算法的过程:
i = 0;则dp[i] = 1,因为此时A[i] = 4,此时只有一个元素构成了子序列
i = 1;则dp[i] = 2,因为此时A[i] = 5,dp[i] = d[0] + 1;
i = 2;则dp[i] = 1,因为此时A[i] = 1,前面并没有一个元素大于A[i],则dp[i] = 1;
i = 3;则dp[i] = 2,因为此时A[i] = 3,那么前面只有A[2]小于A[i],也就是dp[i] = dp[2] + 1 = 2;
i = 4;则dp[i] = 3,因为此时A[I] = 4,那么前面有A[0],A[1],A[2],A[3]小于A[i],此时,这些元素的dp[i]最大的是2,那么就是dp[i] = max(前面最大的dp数组元素) +1;

也就是说,求最大的递增子序列,我们可以,先从数组元素第一位开始遍历,从第一位开始求解以当前元素作为末尾元素的时候数组的最大的递增子序列的元素个数,后面元素i的最大递增子序列元素个数就是前面比list[i]小的元素的最大递增子序列元素个数 + 1。

则该数组的最大子序列元素个数求解算法

int find()
{
	int list[5] = {4,5,1,3,6};
	int dp[5] = {1};
	for(int i = 0; i < 5; i++)
	{
		dp[i] = 1;
		for(nt j = 0; j < i; j++)
		{
			if(list[j] < list[i] && dp[j] >= dp[i])
				dp[i] = dp[j] + 1;
		}
	}
	int max = -1;
	for(nt i = 0; i < 5; i++)
		if(max< dp[i])
			max = dp[i];
	return Max;
}

现在对该算法题目进行算法实现,其实原理也是一样的。

#include <iostream>
#include <algorithm>
using namespace std;
#define maxSize 200//定义最大的数组
int list[maxSize];
int d[maxSize];
int num;//数组的个数
int main()
{
	while(cin >> num)//循环输入
	{
		int max = 0;//定义max最大递增子序列长度为0
		for(int i = 1; i <= num; i++)
		{
			cin >> list[i];//循环输入
		}
		
		for(int i = 1; i <= num; i++)
		{
			max = 0;//设置max的为0,这里max代表循环找到前面最大的递增子序列最大的长度
			for(int j = 1; j < i; j++)//遍历比i小的元素
			{
				if(list[j] < list[i])//如果说,这个元素比list[i]小,就可以再增长
				{
					if(max < d[j])//且此时,我记录下的最大递增子序列长度小于现在这个元素的
					{
						max = d[j];//替换
					}
				}
			}
			d[i] = max + 1;//最后加上向这个i的元素向上走一步
		}
		//循环找到这个d数组里面最大的长度即可
		for(int i = 1; i <= num; i++)
		{
			if (max < d[i]){
				max = d[i];
			}
				
		}
		cout << max << endl;
	}
	
	
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章