题目描述
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
输入描述:
输入多行,先输入数组的个数,再输入相应个数的整数
输出描述:
输出结果
示例1
输入
复制
6
2
5
1
5
4
5
输出
复制
3
题目分析:
本题是一个典型的动态规划算法应用的问题。
DP全称是dynamic programming,这里programming不是编程,是一个表格保存之前的结果。
DP 是一种编程思想,主要用于解决最优解类型的问题。
其思路是为了求解当前的问题的最优解,使用子问题的最优解,然后综合处理,最终得到原问题的最优解。
解题思路:
建立一个数组,专门用来存放以i结尾的最大的升序的子序列的元素个数。
比如
2 5 1 5 4 5
对应的相应位置的最大子序列,及元素个数为
第一个子序列为,长度为1
2 1
第二个子序列,将前面1个元素对比。因为5 > 2,所以
位置2处的最大子序列长度为2。子序列为2 5
2 5 2
以位置3处元素结尾的最大子序列,因为前面的元素都比1小。所以
位置3处的最大子序列长度为1。子序列为1
1 1
位置4处的最大子序列长度为2。子序列为2 5
2 5 2
位置5处的最大子序列长度为2。子序列为2 4
2 4 2
位置6处的最大子序列长度为3。子序列为2 4 5
2 4 5 3
将位置6处的元素与前面5个位置处的元素挨个比较。保存最大值。
和位置1处的元素比较以后,最大值为1+1。
和位置5处的元素比较以后,最大值为2+1。
记录最大值即可。结果为3。
当最大值元素变更时,相应变更系统最大的步数。
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int n, val;
vector<int> arr;
vector<int> step;
while(cin >> n)
{
while(n--)
{
cin >> val;
arr.push_back(val);
step.push_back(1);
}
int max = 0;
for(int i = 1; i < arr.size(); i++)
{
int step_val = 1;
int step_max = 1;
for(int j = 0; j < i; j++)
{
if(arr[i] > arr[j])
{
step_val = step[j] + 1;
if(step_val > step_max)
{
step_max = step_val;
}
}
}
step[i] = step_max;
if(step_max > max)
{
max = step_max;
}
}
arr.clear();
step.clear();
cout << max << endl;
}
return 0;
}