自学内容网 自学内容网

华为OD机试 - 虚拟理财游戏 - 贪心算法(Python/JS/C/C++ 2024 D卷 200分)

在这里插入图片描述

华为OD机试 2024E卷题库疯狂收录中,刷题点这里

专栏导读

本专栏收录于《华为OD机试真题(Python/JS/C/C++)》

刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天CSDN在线答疑。

一、题目描述

在一款虚拟游戏中生活,你必须进行投资以增强在虚拟游戏中的资产以免被淘汰出局。现有一家 Bank,它提供有若干理财产品 m,风险及投资回报不同,你有 N(元)进行投资,能接受的总风险值为 X。

你要在可接受范围内选择最优的投资方式获得最大回报。

说明:

1、在虚拟游戏中,每项投资风险值相加为总风险值;

2、在虚拟游戏中,最多只能投资 2 个理财产品;

3、在虚拟游戏中,最小单位为整数,不能拆分为小数;

投资额*回报率=投资回报

二、输入描述

第一行:产品数(取值范围[1, 20]),总投资额(整数,取值范围[1, 10000]),可接受的总风险(整数,取值范围[1, 200])

第二行:产品投资回报率序列,输入为整数,取值范围[1,60]

第三行:产品风险值序列,输入为整数,取值范围[1,100]

第四行:最大投资额度序列,输入为整数,取值范围[1,10000]

三、输出描述

每个产品的投资额序列。

补充说明

1、在虚拟游戏中,每项投资风险值相加为总风险值;

2、在虚拟游戏中,最多只能投资 2 个理财产品;

3、在虚拟游戏中,最小单位为整数,不能拆分为小数;

投资额*回报率=投资回报

四、测试用例

测试用例1

1、输入

5 100 10
10 20 30 40 50
3 4 5 6 10
20 30 20 40 30

2、输出

0 30 0 40 0

3、说明

投资第二项 30 个单位,第四项 40 个单位,总的投资风险为两项相加为 4+6=10

测试用例2

1、输入

1 1000 100
50
100
1000

2、输出

1000

五、解题思路

这个问题可以看作是一个优化问题,目标是在给定的投资总额和风险限制内,选择最多两个理财产品以获得最大的回报。以下是解决该问题的详细步骤:

  1. 读取输入:
    • 获取产品数量、总投资额、可接受的总风险。
    • 获取每个产品的投资回报率、风险值和最大投资额度。
  2. 初始化变量:
    • 初始化记录最大回报的变量 maxReturn。
    • 初始化记录最小风险的变量 minRisk。
    • 使用一个哈希表 bestInvestment 来记录最佳投资策略。
  3. 单个产品投资的处理:
    • 遍历每个产品,检查单个产品的风险是否在可接受范围内。
    • 计算该产品的实际投资额和投资回报。
    • 如果该产品的投资回报高于当前记录的最大回报,或者在相同回报下风险更低,则更新最佳投资策略。
  4. 两个产品组合投资的处理:
    • 遍历所有可能的产品组合(两个产品的组合)。
    • 检查两个产品的总风险是否在可接受范围内。
    • 根据回报率和风险值的不同情况,计算每个产品的实际投资额和组合投资回报。
    • 如果该组合的投资回报高于当前记录的最大回报,或者在相同回报下风险更低,则更新最佳投资策略。
  5. 输出结果:
    • 遍历所有产品,根据最佳投资策略生成最终的投资额度序列并输出。

六、Python算法源码

# 导入必要的库
import sys
from itertools import combinations

def main():
    # 读取第一行输入:产品数,总投资额,可接受的总风险
    input_line = sys.stdin.readline().strip()
    while input_line == '':
        input_line = sys.stdin.readline().strip()
    product_count, total_investment, total_risk = map(int, input_line.split())

    # 读取第二行输入:产品投资回报率序列
    rates = list(map(int, sys.stdin.readline().strip().split()))

    # 读取第三行输入:产品风险值序列
    risks = list(map(int, sys.stdin.readline().strip().split()))

    # 读取第四行输入:产品最大投资额度序列
    max_investments = list(map(int, sys.stdin.readline().strip().split()))

    # 初始化最大回报和最小风险
    max_return = 0
    min_risk = float('inf')

    # 存储最佳投资策略
    best_investment = {}

    # 枚举所有可能的投资组合
    for i in range(product_count):
        # 单个产品投资
        if risks[i] <= total_risk:
            invest_i = min(max_investments[i], total_investment)
            return_i = invest_i * rates[i]
            if return_i > max_return or (return_i == max_return and risks[i] < min_risk):
                max_return = return_i
                min_risk = risks[i]
                best_investment = {i: invest_i}

        # 枚举与其他产品组合投资
        for j in range(i + 1, product_count):
            combined_risk = risks[i] + risks[j]
            if combined_risk <= total_risk:
                # 优先投资回报率高的产品
                if rates[i] > rates[j]:
                    invest_first = min(max_investments[i], total_investment)
                    invest_second = min(max_investments[j], total_investment - invest_first)
                elif rates[i] < rates[j]:
                    invest_first = min(max_investments[j], total_investment)
                    invest_second = min(max_investments[i], total_investment - invest_first)
                else:
                    # 回报率相同,优先风险低的
                    if risks[i] < risks[j]:
                        invest_first = min(max_investments[i], total_investment)
                        invest_second = min(max_investments[j], total_investment - invest_first)
                    else:
                        invest_first = min(max_investments[j], total_investment)
                        invest_second = min(max_investments[i], total_investment - invest_first)
                
                total_return = invest_first * rates[i] + invest_second * rates[j]
                # 更新最佳投资策略
                if total_return > max_return or (total_return == max_return and combined_risk < min_risk):
                    max_return = total_return
                    min_risk = combined_risk
                    best_investment = {}
                    if invest_first > 0:
                        if rates[i] > rates[j]:
                            best_investment[i] = invest_first
                            best_investment[j] = invest_second
                        else:
                            best_investment[j] = invest_first
                            best_investment[i] = invest_second

    # 构造输出结果
    result = []
    for i in range(product_count):
        result.append(str(best_investment.get(i, 0)))
    print(' '.join(result))

if __name__ == "__main__":
    main()

七、JavaScript算法源码

// 引入必要的模块
const readline = require('readline');

// 创建接口用于读取输入
const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

let inputLines = [];
rl.on('line', (line) => {
    if (line.trim() === '') return;
    inputLines.push(line.trim());
    if (inputLines.length === 4) {
        rl.close();
    }
});

rl.on('close', () => {
    // 解析第一行输入:产品数,总投资额,可接受的总风险
    const [productCount, totalInvestment, totalRisk] = inputLines[0].split(' ').map(Number);

    // 解析第二行输入:产品投资回报率序列
    const rates = inputLines[1].split(' ').map(Number);

    // 解析第三行输入:产品风险值序列
    const risks = inputLines[2].split(' ').map(Number);

    // 解析第四行输入:产品最大投资额度序列
    const maxInvestments = inputLines[3].split(' ').map(Number);

    // 初始化最大回报和最小风险
    let maxReturn = 0;
    let minRisk = Infinity;

    // 存储最佳投资策略
    let bestInvestment = {};

    // 枚举所有可能的投资组合
    for (let i = 0; i < productCount; i++) {
        // 单个产品投资
        if (risks[i] <= totalRisk) {
            let investI = Math.min(maxInvestments[i], totalInvestment);
            let returnI = investI * rates[i];
            if (returnI > maxReturn || (returnI === maxReturn && risks[i] < minRisk)) {
                maxReturn = returnI;
                minRisk = risks[i];
                bestInvestment = {};
                bestInvestment[i] = investI;
            }
        }

        // 枚举与其他产品组合投资
        for (let j = i + 1; j < productCount; j++) {
            let combinedRisk = risks[i] + risks[j];
            if (combinedRisk <= totalRisk) {
                let investFirst, investSecond;
                if (rates[i] > rates[j]) {
                    investFirst = Math.min(maxInvestments[i], totalInvestment);
                    investSecond = Math.min(maxInvestments[j], totalInvestment - investFirst);
                } else if (rates[i] < rates[j]) {
                    investFirst = Math.min(maxInvestments[j], totalInvestment);
                    investSecond = Math.min(maxInvestments[i], totalInvestment - investFirst);
                } else {
                    // 回报率相同,优先风险低的
                    if (risks[i] < risks[j]) {
                        investFirst = Math.min(maxInvestments[i], totalInvestment);
                        investSecond = Math.min(maxInvestments[j], totalInvestment - investFirst);
                    } else {
                        investFirst = Math.min(maxInvestments[j], totalInvestment);
                        investSecond = Math.min(maxInvestments[i], totalInvestment - investFirst);
                    }
                }

                let totalReturn = investFirst * rates[i] + investSecond * rates[j];
                // 更新最佳投资策略
                if (totalReturn > maxReturn || (totalReturn === maxReturn && combinedRisk < minRisk)) {
                    maxReturn = totalReturn;
                    minRisk = combinedRisk;
                    bestInvestment = {};
                    if (investFirst > 0) {
                        if (rates[i] > rates[j]) {
                            bestInvestment[i] = investFirst;
                            bestInvestment[j] = investSecond;
                        } else {
                            bestInvestment[j] = investFirst;
                            bestInvestment[i] = investSecond;
                        }
                    }
                }
            }
        }
    }

    // 构造输出结果
    let result = [];
    for (let i = 0; i < productCount; i++) {
        result.push(bestInvestment[i] || 0);
    }
    console.log(result.join(' '));
});

八、C算法源码

#include <stdio.h>
#include <stdlib.h>

// 定义最大产品数
#define MAX_PRODUCTS 20

int main(){
    int productCount, totalInvestment, totalRisk;
    // 读取第一行输入:产品数,总投资额,可接受的总风险
    scanf("%d %d %d", &productCount, &totalInvestment, &totalRisk);

    int rates[MAX_PRODUCTS];
    // 读取第二行输入:产品投资回报率序列
    for(int i=0;i<productCount;i++) {
        scanf("%d", &rates[i]);
    }

    int risks[MAX_PRODUCTS];
    // 读取第三行输入:产品风险值序列
    for(int i=0;i<productCount;i++) {
        scanf("%d", &risks[i]);
    }

    int maxInvestments[MAX_PRODUCTS];
    // 读取第四行输入:产品最大投资额度序列
    for(int i=0;i<productCount;i++) {
        scanf("%d", &maxInvestments[i]);
    }

    // 初始化最大回报和最小风险
    long long maxReturn = 0;
    int minRisk = 1000000;

    // 存储最佳投资策略
    int bestInvestment[MAX_PRODUCTS];
    for(int i=0;i<productCount;i++) bestInvestment[i] = 0;

    // 枚举所有可能的投资组合
    for(int i=0;i<productCount;i++){
        // 单个产品投资
        if(risks[i] <= totalRisk){
            int investI = (maxInvestments[i] < totalInvestment) ? maxInvestments[i] : totalInvestment;
            long long returnI = (long long)investI * rates[i];
            if(returnI > maxReturn || (returnI == maxReturn && risks[i] < minRisk)){
                maxReturn = returnI;
                minRisk = risks[i];
                // 重置最佳投资
                for(int k=0;k<productCount;k++) bestInvestment[k] = 0;
                bestInvestment[i] = investI;
            }
        }

        // 枚举与其他产品组合投资
        for(int j=i+1;j<productCount;j++){
            int combinedRisk = risks[i] + risks[j];
            if(combinedRisk <= totalRisk){
                int investFirst, investSecond;
                if(rates[i] > rates[j]){
                    investFirst = (maxInvestments[i] < totalInvestment) ? maxInvestments[i] : totalInvestment;
                    investSecond = (maxInvestments[j] < (totalInvestment - investFirst)) ? maxInvestments[j] : (totalInvestment - investFirst);
                }
                else if(rates[i] < rates[j]){
                    investFirst = (maxInvestments[j] < totalInvestment) ? maxInvestments[j] : totalInvestment;
                    investSecond = (maxInvestments[i] < (totalInvestment - investFirst)) ? maxInvestments[i] : (totalInvestment - investFirst);
                }
                else{
                    // 回报率相同,优先风险低的
                    if(risks[i] < risks[j]){
                        investFirst = (maxInvestments[i] < totalInvestment) ? maxInvestments[i] : totalInvestment;
                        investSecond = (maxInvestments[j] < (totalInvestment - investFirst)) ? maxInvestments[j] : (totalInvestment - investFirst);
                    }
                    else{
                        investFirst = (maxInvestments[j] < totalInvestment) ? maxInvestments[j] : totalInvestment;
                        investSecond = (maxInvestments[i] < (totalInvestment - investFirst)) ? maxInvestments[i] : (totalInvestment - investFirst);
                    }
                }

                long long totalReturn = (long long)investFirst * rates[i] + (long long)investSecond * rates[j];
                // 更新最佳投资策略
                if(totalReturn > maxReturn || (totalReturn == maxReturn && combinedRisk < minRisk)){
                    maxReturn = totalReturn;
                    minRisk = combinedRisk;
                    // 重置最佳投资
                    for(int k=0;k<productCount;k++) bestInvestment[k] = 0;
                    if(investFirst > 0){
                        if(rates[i] > rates[j]){
                            bestInvestment[i] = investFirst;
                            bestInvestment[j] = investSecond;
                        }
                        else{
                            bestInvestment[j] = investFirst;
                            bestInvestment[i] = investSecond;
                        }
                    }
                }
            }
        }
    }

    // 输出最佳投资组合
    for(int i=0;i<productCount;i++){
        if(i != 0) printf(" ");
        printf("%d", bestInvestment[i]);
    }
    printf("\n");
    return 0;
}

九、C++算法源码

#include <bits/stdc++.h>
using namespace std;

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);

    int productCount, totalInvestment, totalRisk;
    // 读取第一行输入:产品数,总投资额,可接受的总风险
    cin >> productCount >> totalInvestment >> totalRisk;

    vector<int> rates(productCount);
    // 读取第二行输入:产品投资回报率序列
    for(auto &x : rates) cin >> x;

    vector<int> risks(productCount);
    // 读取第三行输入:产品风险值序列
    for(auto &x : risks) cin >> x;

    vector<int> maxInvestments(productCount);
    // 读取第四行输入:产品最大投资额度序列
    for(auto &x : maxInvestments) cin >> x;

    // 初始化最大回报和最小风险
    long long maxReturn = 0;
    int minRisk = INT32_MAX;

    // 存储最佳投资策略
    vector<int> bestInvestment(productCount, 0);

    // 枚举所有可能的投资组合
    for(int i=0;i<productCount;i++){
        // 单个产品投资
        if(risks[i] <= totalRisk){
            int investI = min(maxInvestments[i], totalInvestment);
            long long returnI = (long long)investI * rates[i];
            if(returnI > maxReturn || (returnI == maxReturn && risks[i] < minRisk)){
                maxReturn = returnI;
                minRisk = risks[i];
                fill(bestInvestment.begin(), bestInvestment.end(), 0);
                bestInvestment[i] = investI;
            }
        }

        // 枚举与其他产品组合投资
        for(int j=i+1;j<productCount;j++){
            int combinedRisk = risks[i] + risks[j];
            if(combinedRisk <= totalRisk){
                int investFirst, investSecond;
                if(rates[i] > rates[j]){
                    investFirst = min(maxInvestments[i], totalInvestment);
                    investSecond = min(maxInvestments[j], totalInvestment - investFirst);
                }
                else if(rates[i] < rates[j]){
                    investFirst = min(maxInvestments[j], totalInvestment);
                    investSecond = min(maxInvestments[i], totalInvestment - investFirst);
                }
                else{
                    // 回报率相同,优先风险低的
                    if(risks[i] < risks[j]){
                        investFirst = min(maxInvestments[i], totalInvestment);
                        investSecond = min(maxInvestments[j], totalInvestment - investFirst);
                    }
                    else{
                        investFirst = min(maxInvestments[j], totalInvestment);
                        investSecond = min(maxInvestments[i], totalInvestment - investFirst);
                    }
                }

                long long totalReturn = (long long)investFirst * rates[i] + (long long)investSecond * rates[j];
                // 更新最佳投资策略
                if(totalReturn > maxReturn || (totalReturn == maxReturn && combinedRisk < minRisk)){
                    maxReturn = totalReturn;
                    minRisk = combinedRisk;
                    fill(bestInvestment.begin(), bestInvestment.end(), 0);
                    if(investFirst > 0){
                        if(rates[i] > rates[j]){
                            bestInvestment[i] = investFirst;
                            bestInvestment[j] = investSecond;
                        }
                        else{
                            bestInvestment[j] = investFirst;
                            bestInvestment[i] = investSecond;
                        }
                    }
                }
            }
        }
    }

    // 输出最佳投资组合
    for(int i=0;i<productCount;i++){
        if(i !=0 ) cout << ' ';
        cout << bestInvestment[i];
    }
    cout << '\n';
    return 0;
}


🏆下一篇:华为OD机试真题 - 简易内存池(Python/JS/C/C++ 2024 E卷 200分)

🏆本文收录于,华为OD机试真题(Python/JS/C/C++)

刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天CSDN在线答疑。

在这里插入图片描述


原文地址:https://blog.csdn.net/guorui_java/article/details/142989955

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!