题解 | 最长不下降子序列
最长不下降子序列
https://www.nowcoder.com/practice/25da45d0d4fb4faba45094cbb0649062
import java.util.Scanner;
import java.util.Arrays;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int a=in.nextInt();
int s[]=new int[a];
int dp[] =new int[a];
int flag=1;
int i ,j,ml=1;
for(i=0;i<a;i++){
s[i]=in.nextInt();
}
Arrays.fill(dp,1);
for(i=0;i<s.length-1;i++){
for(j=i+1;j<s.length;j++){
if(s[i]<=s[j]){
//dp[j]=dp[i]+1;
dp[j]=Math.max(dp[i]+1,dp[j]);
ml=Math.max(ml,dp[j]);
}
}
}
System.out.print(ml);
}
}
状态转移方程: dp[j]=Math.max(dp[i]+1,dp[j]);
思路:
观察示例一中的子序列,第i个数字的最长序列由i-1个数字的最长序列获得
得到一个假的状态方程:dp[j]=dp[i]+1;
去循环遍历填表:
for(i=0;i<s.length-1;i++){
for(j=i+1;j<s.length;j++){
if(s[i]<=s[j]){
dp[j]=dp[i]+1;
}
}
}
可以对一些实例,
发现一个新的问题,在某个实例中,条件s[i]<=s[j]满足,但是dp[j]在其他循环中记录的最长序列,比当前要记录的最长序列dp[i]+1大,所以dp[j]被覆盖成最小了,
所以要在dp[i]+1和dp[j]中取最大值来记录
新的状态转移方程: dp[j]=Math.max(dp[i]+1,dp[j]);
但是还是不能全对
以下面为例;
10
298442 20400 774061 202518 319008 514069 740053 470905 431457 66193
dp数组中内容是
121222221
22222222
2222222
333332
44442
5442
442
42
2
发现整个序列的最大序列记录值不在最后,所以需要一个ml记录最大值输出
