题目描述
Redraiment是走梅花桩的高手。Redraiment可以选择任意一个起点,从前到后,但只能从低处往高处的桩子走。他希望走的步数最多,
你能替Redraiment研究他最多走的步数吗?
本题含有多组样例输入
输入描述:
输入多行,先输入数组的个数,再输入相应个数的整数
输出描述:
输出结果
示例1
输入
6 2 5 1 5 4 5 3 3 2 1输出
3 1说明
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
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
using namespace std;
//典型的上升子序列,利用动态规划
int mostWays(vector<int>& nums){
// //二维dp
// if(nums.empty()) return 0;
// int n=nums.size();
// int dp[n][n];
// memset(dp,0,sizeof(dp));
// //从前到后,边界条件
// for(int i=0;i<n;i++) dp[i][i]=1;//起始为1
// int res=1;
// for(int i=0;i<n;++i){
// for(int j=i+1;j<n;++j){
// if(nums[j]>nums[i]){
// dp[i][j]=dp[i][i]+1;
// //j所在的位置,dp[j][j]发生了变化需要记录此时最大者
// dp[j][j]=max(dp[i][j],dp[j][j]);
// }else{
// dp[i][j]=dp[i][i];
// }
// res=max(dp[i][j],res);
// }
// }
//状态压缩
int n=nums.size(),res=0;
vector<int> dp(n,1);//最小子序列初始化为1
for(int i=0;i<n;++i){
for(int j=0;j<i;++j){
if(nums[i]>nums[j]){
dp[i]=max(dp[i],dp[j]+1);//维持一个最大的递增序列
}
}
res=max(dp[i],res);
}
return res;
}
int main(int argc,char* argv[]){
int n;
while(cin>>n){
vector<int> nums(n);
for(int i=0;i<n;i++) cin>>nums[i];
cout<<mostWays(nums)<<endl;
}
return 0;
}