【华为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];
}

注意:

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

相关推荐
violin-wang3 分钟前
Intellij IDEA如何查看当前文件的类
java·ide·intellij-idea
【 】4233 分钟前
安卓7以上抓包证书安装
android·javascript·爬虫·网络爬虫
圆圆同学17 分钟前
Springboot实现TLS双向认证
java·spring boot·后端
羚羊角uou18 分钟前
【C++】多态详细讲解
开发语言·c++
大地爱19 分钟前
基于SpringBoot和PostGIS的各国及所属机场信息检索及可视化实现
java·spring boot·spring
荔枝味啊~30 分钟前
杭州某小厂面试
java·网络·数据库·tcp/ip·面试
蹦蹦跳跳真可爱58930 分钟前
Python----Python高级(并发编程:协程Coroutines,事件循环,Task对象,协程间通信,协程同步,将协程分布到线程池/进程池中)
python
wl85111 小时前
Vue 入门到实战 八
前端·javascript·vue.js
利刃大大1 小时前
【C++】string类的模拟实现
开发语言·c++
九圣残炎1 小时前
【异常记录Java-20250204】调用讯飞星火AI(Spark lite 版本)Api 授权错误问题处理
java·人工智能·spring·spark