我是一个菜鸟,在C语言网做题的时候,做到可能别人觉得很简单的题目,但是自己却很难理解,我花了一会时间才看懂整个程序,也就是今天的主角,最长不下降子序列!
题目的链接在这:https://www.dotcpp.com/oj/problem1557.html
题目描述
如果有人认为吃东西只需要嘴巴,那就错了。
都知道舌头有这么一个特性,“由简入奢易,由奢如简难”(据好事者考究,此规律也适合许多其他情况)。具体而言,如果是甜食,当你吃的食物不如前面刚吃过的东西甜,就很不爽了。大宝是一个聪明的美食家,当然深谙此道。一次他来到某小吃一条街,准备从街的一头吃到另一头。为了吃得爽,他大费周章,得到了各种食物的“美味度”。他拒绝不爽的经历,不走回头路而且还要爽歪歪(爽的次数尽量多)。
数据规模和约定
美味度为0到100的整数
n< 1000
输入
两行数据。
第一行为一个整数n,表示小吃街上小吃的数量
第二行为n个整数,分别表示n种食物的“美味度”
输出
一个整数,表示吃得爽的次数
样例输入
10 3 18 7 14 10 12 23 41 16 24
样例输出
6
样例中的输出为6,也就是按照顺序3、7、10、12、16、24来吃的,这就是一个很明显的最长不下降子序列的例题!
解释都在代码里了,看完应该就懂了!
import java.util.Scanner;
class Main
{
public static void main(String[] args){
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
//接收输入的数组
int[] arr = new int[n];
//记录对应arr下标相同的数的最大子序列长度
int[] dp = new int[n];
//记录最大的dp[i]
int ans = 0;
//接收输入的数组以及遍历dp[i]为1
for(int i=0;i<n;i++){
arr[i] = scanner.nextInt();
dp[i] = 1;
}
//从1开始遍历数组
for(int i=1;i<=n-1;i++){
//在i的时候,从i-1开始从后往前遍历
for(int j=i-1;j>=0;j--){
//如果前面有数字小于等于当前遍历的arr[i]
if(arr[j] <= arr[i]){
//就需要选择一个较大的数来更新dp[i]
//dp[j]的意思就是在j的位置的最大子序列
dp[i] = Math.max(dp[i],dp[j]+1);
}
}
if(dp[i] > ans){
ans = dp[i]; //更新ans
}
System.out.print(ans); //输出ans
}
scanner.close();
}
}