HJ103 Redraiment 的走法-最长递增序列

HJ103 Redraiment 的走法

描述

Redraiment 是走梅花桩的高手。Redraiment 可以选择任意一个起点,从前到后,但只能从低处往高处的桩子走。他希望走的步数最多,你能替 Redraiment 研究他最多走的步数吗?

数据范围:每组数据长度满足 1≤n≤200 1≤n≤200 , 数据大小满足 1≤val≤350 1≤val≤350

输入描述:

数据共 2 行,第 1 行先输入数组的个数,第 2 行再输入梅花桩的高度

输出描述:

输出一个结果

示例 1

输入:

6
2 5 1 5 4 5

输出:

3

说明:

6 个点的高度各为 2 5 1 5 4 5
如从第 1 格开始走,最多为 3 步, 2 4 5 ,下标分别是 1 5 6
从第 2 格开始走,最多只有 1 步,5
而从第 3 格开始走最多有 3 步,1 4 5, 下标分别是 3 5 6
从第 5 格开始走最多有 2 步,4 5, 下标分别是 5 6
所以这个结果是 3。

题解

最长递增子序列介绍

最长递增子序列(Longest Increasing Subsequence)是一个经典的动态规划问题。给定一个整数序列,找到其中的一个最长子序列,使得子序列中的元素是递增的。

以下是一个使用动态规划解决最长递增子序列问题的示例代码:


import java.util.Arrays;

public class LongestIncreasingSubsequence {
    public static int lengthOfLIS(int[] nums) {
        if (nums == null || nums.length == 0) {
            return 0;
        }

        int n = nums.length;
        int[] dp = new int[n];
        Arrays.fill(dp, 1); // 初始化每个元素的最长递增子序列长度为1

        int maxLen = 1; // 最长递增子序列的长度

        for (int i = 1; i < n; i++) {
            for (int j = 0; j < i; j++) {
                if (nums[i] > nums[j]) {
                    dp[i] = Math.max(dp[i], dp[j] + 1);
                }
            }
            maxLen = Math.max(maxLen, dp[i]);
        }

        return maxLen;
    }

    public static void main(String[] args) {
        int[] nums = {10, 9, 2, 5, 3, 7, 101, 18};
        int length = lengthOfLIS(nums);
        System.out.println("最长递增子序列的长度为:" + length);
    }
}

在上面的代码中,使用一个数组 dp 来存储以第 i 个元素结尾的最长递增子序列的长度。初始化每个元素的最长递增子序列长度为 1。然后,依次遍历数组中的每个元素 nums[i],对于每个元素 nums[i],从第一个元素到第 i-1 个元素进行比较,如果存在比 nums[i] 小的元素 nums[j],则更新 dp[i] = dp[j] + 1。最终的最长递增子序列的长度就是 dp 数组中的最大值。

上述代码的输出结果为:

最长递增子序列的长度为:4

对于给定的整数序列 [10, 9, 2, 5, 3, 7, 101, 18],最长递增子序列是 [2, 5, 7, 101],长度为 4。

最长递增子序列解决问题
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);
        // 注意 hasNext 和 hasNextLine 的区别
        while (in.hasNext()) { // 注意 while 处理多个 case
            //  数据共2行,第1行先输入数组的个数,第2行再输入梅花桩的高度
            //  Redraiment是走梅花桩的高手。
            //  Redraiment可以选择任意一个起点,从前到后,但只能从低处往高处的桩子走。
            //  他希望走的步数最多,你能替Redraiment研究他最多走的步数吗?

            int n = in.nextInt();// 数组的个数
            int []numH = new int[n];

            for (int i = 0; i < n; i++) {
                int h = in.nextInt();// 梅花桩的高度
                numH[i] = h;
            }

            //最长递增子序列
            int []dp = new int [n];
            // 初始化每个元素的最长递增子序列为1
            Arrays.fill(dp, 1);
            // 最长递增子序列的长度
            int max = 1;
            for(int i=1;i<n;i++){
                for(int j=0;j<i;j++){
                    if(numH[j]<numH[i]){
                        dp[i]=Math.max(dp[i],dp[j]+1);
                    }
                }
                max = Math.max(max,dp[i]);
            }
            System.out.println(max);
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值