【华为机考E卷】-“最长连续子序列”题解思路java

算法每一题,成长每一天~

C0E15 最长连续子序列

真题链接:【持续更新】2024华为 OD 机试E卷 机考真题库清单(全真题库)

思路

在这里插入图片描述

完全没有思路。

然后 deepseek 用了6分钟十几页的分析,给出了答案。
在这里插入图片描述
思路如下:
在这里插入图片描述

在这里插入图片描述将其当做一个《背包问题》,但是需要恰好装满背包(即“重量”必需等于sum而不是小于等于)。

期间 deepseek 分析了很多贪心算法的思路,最后发现不可取,仍然回归到 动态规划 上。

在这里插入图片描述

Java

import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
import java.util.stream.Collectors;

public class C0E15 {

    public static void main(String[] args) {

        Scanner in = new Scanner(System.in);

        String line = in.nextLine();
        int R = in.nextInt();
        List<Integer> numList =
                Arrays.stream(line.split(","))
                      .map(Integer::parseInt)
                      .sorted() 			// 小到大排序
                      .collect(Collectors.toList());

        int[] dp = new int[R + 1];
        Arrays.fill(dp, Integer.MIN_VALUE); // 赋初始值,-1 或 -∞ 都行
        dp[0] = 0; // 初始条件:和为0时,0个数

        for (int num : numList) {
            if (num > R) {
                break; // 后面的数都比目标大,直接结束
            }

            for (int j = R; j >= num; j--) { // 这里必需 从大到小 遍历,确保每个 num 只用一遍

                // if=true表示:总和 j-num,可以通过前面已经遍历过的数组合得到,且 dp[j-num] 就是组合的最大个数
                if (dp[j - num] != Integer.MIN_VALUE) { 
                    // 那么:总和为 j 的最大个数 等于 dp[j-num] + 1
                    dp[j] = Math.max(dp[j], dp[j - num] + 1);
                }
            }
        }

        // 测例:[1,1,2,3,20,20,30,40], R=32
        System.out.println(dp[R] > 0 ? dp[R] : -1);
    }
}

总结

1、deepseek的解释
在这里插入图片描述
2、典型题目!《0-1背包问题》的变种。

  • 普通背包问题,只要能装得下的情况下,求最大值。
  • 这里要求,必需恰好装满的情况下,求最大值。

3、测例运行结果

测例:
1,1,2,3,20,20,30,40
32

dp[]结果如下:

0 = 0
1 = 1
2 = 2
3 = 2
4 = 3
5 = 3
6 = 3
7 = 4
8 = -2147483648
9 = -2147483648
10 = -2147483648
11 = -2147483648
12 = -2147483648
13 = -2147483648
14 = -2147483648
15 = -2147483648
16 = -2147483648
17 = -2147483648
18 = -2147483648
19 = -2147483648
20 = 1
21 = 2
22 = 3
23 = 3
24 = 4
25 = 4
26 = 4
27 = 5
28 = -2147483648
29 = -2147483648
30 = 1
31 = 2
32 = 3

可以看到,在必需恰好装满的情况下,有些值是不可达的(= -2147483648),即:无法通过任何组合得到这个值。

4、这里如果要输出最长组合的每个数,该怎么做呢?


算法要多练多练多练!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值