【华为OD-E卷 - 113 跳格子2 100分(python、java、c++、js、c)】

【华为OD-E卷 - 跳格子2 100分(python、java、c++、js、c)】

题目

小明和朋友玩跳格子游戏,有 n 个连续格子组成的圆圈,每个格子有不同的分数,小朋友可以选择以任意格子起跳,但是不能跳连续的格子,不能回头跳,也不能超过一圈;
给定一个代表每个格子得分的非负整数数组,计算能够得到的最高分数

输入描述

  • 给定一个数例,第一个格子和最后一个格子首尾相连,如: 2 3 2

输出描述

  • 输出能够得到的最高分,如: 3

备注

  • 1 ≤ nums.length ≤ 100 1 ≤ nums[i] ≤ 1000

用例

用例一:
输入:
复制代码
2 3 2
输出:
复制代码
3
用例二:
输入:
复制代码
1 2 3 1
输出:
复制代码
4

python解法

  • 解题思路:
python 复制代码
# 读取输入数据,将其转换为整数列表
vals = list(map(int, input().split()))

# 计算线性数组的最大不相邻子序列和
def max_points(arr):
    n = len(arr)
    
    # 如果数组只有一个元素,直接返回它
    if n == 1:
        return arr[0]
    
    # 初始化 dp 数组
    p = [0] * n
    
    # 只有一个元素时,最大值就是该元素
    p[0] = arr[0]
    
    # 如果有两个元素,取较大的那个
    if n > 1:
        p[1] = max(arr[0], arr[1])
    
    # 动态规划填充数组
    for i in range(2, n):
        # 核心转移方程:当前最优解 = max(不选当前元素, 选当前元素)
        p[i] = max(p[i-1], p[i-2] + arr[i])
    
    # 返回最后一个位置的最大值,即最终结果
    return p[-1]

# 计算环形数组的最大不相邻子序列和
def find_max():
    # 如果数组只有一个元素,直接返回它
    if len(vals) == 1:
        return vals[0]
    
    # 取两种情况的最大值
    return max(max_points(vals[:-1]), max_points(vals[1:]))

# 输出最终结果
print(find_max())

java解法

  • 解题思路
java 复制代码
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        // 读取输入,使用空格分隔字符串,并转换为整数数组
        String[] input = sc.nextLine().split(" ");
        int[] vals = new int[input.length];
        for (int i = 0; i < input.length; i++) {
            vals[i] = Integer.parseInt(input[i]);
        }

        // 计算并输出最大得分
        System.out.println(findMax(vals));
    }

    // 计算线性数组的最大不相邻子序列和
    public static int maxPoints(int[] arr) {
        int n = arr.length;
        
        // 只有一个元素,直接返回它
        if (n == 1) {
            return arr[0];
        }

        // 动态规划数组
        int[] p = new int[n];

        // 初始状态
        p[0] = arr[0];

        // 只有两个元素时,取较大的
        if (n > 1) {
            p[1] = Math.max(arr[0], arr[1]);
        }

        // 递推填充动态规划数组
        for (int i = 2; i < n; i++) {
            p[i] = Math.max(p[i - 1], p[i - 2] + arr[i]);
        }

        // 返回最后一个位置的最大值
        return p[n - 1];
    }

    // 计算环形数组的最大不相邻子序列和
    public static int findMax(int[] vals) {
        int n = vals.length;

        // 如果数组只有一个元素,直接返回它
        if (n == 1) {
            return vals[0];
        }

        // 创建两个新的数组:
        // 1. vals1 代表去掉最后一个元素的子数组
        // 2. vals2 代表去掉第一个元素的子数组
        int[] vals1 = new int[n - 1];
        int[] vals2 = new int[n - 1];

        // 复制 vals[0] 到 vals[n-2] 形成 vals1
        System.arraycopy(vals, 0, vals1, 0, n - 1);

        // 复制 vals[1] 到 vals[n-1] 形成 vals2
        System.arraycopy(vals, 1, vals2, 0, n - 1);

        // 取两个子数组的最大得分
        return Math.max(maxPoints(vals1), maxPoints(vals2));
    }
}

C++解法

  • 解题思路
cpp 复制代码
更新中

C解法

解题思路

c 复制代码
更新中

JS解法

解题思路

javascript 复制代码
const readline = require("readline");

const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout,
});

// 监听标准输入,读取一行数据
rl.on("line", (line) => {
    // 将输入字符串拆分成整数数组
    const nums = line.split(" ").map(Number);
    
    // 计算最大得分并输出
    console.log(computeMaxScore(nums));
});

/**
 * 计算环形数组的最大不相邻子序列和
 * @param {number[]} nums 输入的环形数组
 * @returns {number} 最大得分
 */
function computeMaxScore(nums) {
    const n = nums.length;

    // 如果数组只有一个元素,直接返回它
    if (n === 1) return nums[0];

    // 计算去掉最后一个元素 和 去掉第一个元素 两种情况的最大值
    return Math.max(calcMax(nums.slice(0, -1)), calcMax(nums.slice(1)));
}

/**
 * 计算线性数组的最大不相邻子序列和(递归+记忆化)
 * @param {number[]} arr 线性数组
 * @returns {number} 最大得分
 */
function calcMax(arr) {
    // 创建 memo 数组用于记忆化,初始值为 -1,表示未计算
    const memo = new Array(arr.length).fill(-1);
    
    // 调用递归计算最大得分
    return maxWithMemo(arr, arr.length - 1, memo);
}

/**
 * 递归计算最大得分,使用记忆化优化
 * @param {number[]} arr 线性数组
 * @param {number} i 当前索引
 * @param {number[]} memo 记忆化数组
 * @returns {number} 计算到 i 位置的最大得分
 */
function maxWithMemo(arr, i, memo) {
    // 边界情况:索引小于 0,返回 0(无贡献)
    if (i < 0) return 0;

    // 如果 memo[i] 已经计算过,直接返回
    if (memo[i] !== -1) return memo[i];

    // 计算当前索引的最优解,并存入 memo 数组
    memo[i] = Math.max(
        maxWithMemo(arr, i - 1, memo),       // 不取 arr[i],继承之前的最大值
        maxWithMemo(arr, i - 2, memo) + arr[i] // 取 arr[i],但必须跳过 arr[i-1]
    );

    return memo[i];
}

注意:

如果发现代码有用例覆盖不到的情况,欢迎反馈!会在第一时间修正,更新。
解题不易,如对您有帮助,欢迎点赞/收藏

相关推荐
Liii403几秒前
Java学习——数据库查询操作
java·数据库·学习
f狐0狸x5 分钟前
【蓝桥杯每日一题】3.17
c语言·c++·算法·蓝桥杯·二进制枚举
色楠不哭5 分钟前
python包filterpy安装失败ModuleNotFoundError: No module named ‘filterpy‘
开发语言·python
Aaron.Ma13 分钟前
Django 问题
python·django·sqlite
范哥来了14 分钟前
python web开发flask库安装与使用
前端·python·flask
爱做ppt的阿伟18 分钟前
一键爬取b站视频
python·音视频
PXM的算法星球24 分钟前
Java爬虫抓取B站视频信息
java·windows·爬虫
李恩泽的博客31 分钟前
Python 使用PIL将图片或GIF转字符画
python
斯内普的小巨怪43 分钟前
项目问答(自用记录)
python
皮卡兔子屋1 小时前
redis过期删除、内存淘汰、双写一致性---java
java·redis·mybatis