【华为OD机试真题】- 虚拟游戏理财(JS解答)

题目描述:
在一款虚拟游戏中生活,你必须进行投资以增强在虚拟游戏中的资产以免被淘汰出局。现有一家Bank,它提供有若干理财产品 m 个,风险及投资回报不同,你有N(元)进行投资,能接收的总风险值为X。你要在可接受范围内选择最优的投资方式获得最大回报。
备注:
在虚拟游戏中,每项投资风险值相加为总风险值;
在虚拟游戏中,最多只能投资2个理财产品;
在虚拟游戏中,最小单位为整数,不能拆分为小数;
投资额*回报率 = 投资回报

输入描述:
第一行:
产品数(取值范围[1,20])
总投资额(整数,取值范国[1, 100001)
可接受的总风险 (整数,取值范围[1,200])
第二行:产品投资回报率Q序列,输入为整数,取值范国(1,60]
第三行:产品风险值序列,输入为整数,取值范国(1,100]
第四行:最大投资额度序列,输入为整数,取值范国(1,10000]

输出描述:
每个产品的投资额序列

示例1
输入:
5 100 10
10 20 30 40 50
3 4 5 6 10
20 30 20 40 30
输出:
0 30 0 40 0
说明:投资第二项30个单位,第四项40个单位,总的投资风险为两项相加为4+6=10

JS参考解题:

解题思路:
可以通过动态规划来解决。我们可以定义一个三维数组 dp[i][j][k],表示投资前 i 个理财产品,总投资额不超过 j,总风险不超过 k 的情况下,能获得的最大回报。然后我们可以根据这个二维数组逆向推导出每个产品的投资额。

function maxReturn(products, totalInvestment, maxRisk, returns, risks, maxInvestments) {
    const n = products; // 产品数
    const m = totalInvestment; // 总投资额
    const x = maxRisk; // 可接受的总风险

    // 初始化 dp 数组
    const dp = Array.from({ length: n + 1 }, () =>
        Array.from({ length: m + 1 }, () => Array(x + 1).fill(0))
    );
    for (let i = 1; i <= n; i++) {
        for (let j = 1; j <= m; j++) {
            for (let k = 1; k <= x; k++) {
                dp[i][j][k] = dp[i - 1][j][k]; // 不投资第 i 个产品的情况
                if (risks[i - 1] <= k && maxInvestments[i - 1] <= j) { // 如果第 i 个产品的风险小于等于当前风险值,并且投资额小于等于总投资额
                    dp[i][j][k] = Math.max(dp[i][j][k], dp[i - 1][j - maxInvestments[i - 1]][k - risks[i - 1]] + returns[i - 1]); // 投资第 i 个产品的情况
                }
            }
        }
    }

    // 根据 dp 数组逆向推导每个产品的投资额
    let j = m;
    let k = x;
    const investments = Array(n).fill(0);
    for (let i = n; i > 0 && j > 0 && k > 0; i--) {
        if (dp[i][j][k] !== dp[i - 1][j][k]) { // 如果投资了第 i 个产品
            investments[i - 1] = maxInvestments[i - 1]; // 投资额为最大投资额
            j -= maxInvestments[i - 1]; // 减去投资的额度
            k -= risks[i - 1]; // 减去投资的风险值
        }
    }

    return investments.join(" ");
}

// 示例输入
const products = 5;
const totalInvestment = 100;
const maxRisk = 10;
const returns = [10, 20, 30, 40, 50];
const risks = [3, 4, 5, 6, 10];
const maxInvestments = [20, 30, 20, 40, 30];

// 输出
console.log(maxReturn(products, totalInvestment, maxRisk, returns, risks, maxInvestments)); 
  • 9
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
华为OD-学生重新排队是一个典的编程问,下面是问和解决路: 问描述: 有n个学生站成一排,每个学生都有一个独一无二身份ID。现在给定一个初始的学生排列顺序,以及一系列的交换操作,交换操作表示将两个学生的位置进行交换。请你编写一个算法,输出最终的学生排列顺序。 解决思路: 这个问可以使用数组来表示学生的排列顺序。首先,我们需要根据初始的学生排列顺序构建一个映射表,将每个学生的ID与其在数组中的位置对应起来。然后,我们按照给定的交换操作,更新映射表中学生的位置信息。最后,根据更新后的映射表,构建最终的学生排列顺序。 具体步骤如下: 1. 构建映射表:遍历初始的学生排列顺序,将每个学生的ID与其在数组中的位置对应起来,可以使用哈希表来实现。 2. 执行交换操作:按照给定的交换操作,更新映射表中学生的位置信息。 3. 构建最终的学生排列顺序:根据更新后的映射表,构建最终的学生排列顺序。 下面是一个示例代码,用于解决这个问: ```python def rearrange_students(initial_order, swap_operations): # 构建映射表 mapping = {} for i, student_id in enumerate(initial_order): mapping[student_id] = i # 执行交换操作 for swap in swap_operations: student1, student2 = swap mapping[student1], mapping[student2] = mapping[student2], mapping[student1] # 构建最终的学生排列顺序 final_order = [0] * len(initial_order) for student_id, position in mapping.items(): final_order[position] = student_id return final_order ``` 使用上述代码,你可以通过传入初始的学生排列顺序和交换操作,得到最终的学生排列顺序。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值