• 虚拟游戏理财 - 华为OD统一考试(C卷)


    OD统一考试(C卷)

    分值: 100分

    题解: Java / Python / C++

    alt

    题目描述

    在一款虚拟游戏中生活,你必须进行投资以增强在虚拟游戏中的资产以免被淘汰出局。

    现有一家Bank,它提供有若干理财产品m,风险及投资回报不同,你有N (元)进行投资,能接受的总风,险值为X。

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

    说明:

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

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

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

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

    输入描述

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

    第二行:产品投资回报率序列,输入为整数,取值范围[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。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    题解

    这道题是一个简单的贪心算法问题。下面是解题思路和代码的分析:

    • 题目类型:贪心算法问题。
    • 解题思路:通过贪心算法选择最优的投资方式,即在可接受范围内选择回报率高且风险低的投资方案。
    • 代码描述:
      1. 读取输入数据:产品数、总投资额、可接受的总风险,产品投资回报率序列,产品风险值序列,最大投资额度序列。
      2. 初始化最大收益为0,创建一个空的字典rs用于存储最优投资数量。
      3. 遍历产品,对于每个产品:
        • 如果该产品的风险超过了可接受的总风险,则跳过该产品。
        • 计算只投资该产品时的投资数量,更新最大收益和最优投资数量。
        • 遍历剩余产品,计算两种产品组合的投资数量,更新最大收益和最优投资数量。
      4. 输出最优投资数量序列。
    • 时间复杂度:假设产品数为m,则时间复杂度为O(m^2)。
    • 空间复杂度:空间复杂度取决于存储最优投资数量的字典rs,最坏情况下为O(m)。

    Java

    import java.util.Arrays;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Scanner;
    /**
     * @author code5bug
     */
    public class Main {
    
        public static void main(String[] args) {
            Scanner in = new Scanner(System.in);
            // 产品数,总投资额,可接受的总风险
            int m = in.nextInt(), n = in.nextInt(), x = in.nextInt();
            in.nextLine(); // 忽略换行符
    
            // 产品投资回报率序列
            int[] reward = Arrays.stream(in.nextLine().split(" "))
                    .mapToInt(Integer::parseInt).toArray();
    
            // 产品风险值序列
            int[] risk = Arrays.stream(in.nextLine().split(" "))
                    .mapToInt(Integer::parseInt).toArray();
    
            // 最大投资额度序列
            int[] restrict = Arrays.stream(in.nextLine().split(" "))
                    .mapToInt(Integer::parseInt).toArray();
    
            int maxReward = 0; // 最大收益
            Map<Integer, Integer> rs = new HashMap<>();
            for (int i = 0; i < m; i++) {
                if (risk[i] > x) continue;
    
                // 只购买 i 产品
                int k = Math.min(restrict[i], n);
                if (reward[i] * k > maxReward) {
                    rs.clear();
                    rs.put(i, k);
                    maxReward = reward[i] * k;
                }
    
                for (int j = i + 1; j < m; j++) {
                    if (risk[i] + risk[j] > x) continue;
    
                    int cnti = restrict[i], cntj = restrict[j];
                    if (reward[i] > reward[j]) {
                        cnti = Math.min(cnti, n);
                        cntj = Math.min(cntj, n - cnti);
                    } else {
                        cntj = Math.min(cntj, n);
                        cnti = Math.min(cnti, n - cntj);
                    }
    
                    if (reward[i] * cnti + reward[j] * cntj > maxReward) {
                        rs.clear();
                        rs.put(i, cnti);
                        rs.put(j, cntj);
                        maxReward = reward[i] * cnti + reward[j] * cntj;
                    }
                }
            }
    
            StringBuilder builder = new StringBuilder();
            for (int i = 0; i < m; i++) {
                builder.append(rs.getOrDefault(i, 0)).append(" ");
            }
    
            System.out.println(builder.toString());
        }
    
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71

    Python

    # 导入必要的模块
    from collections import defaultdict
    
    # 获取输入数据
    m, n, x = map(int, input().split())
    reward = list(map(int, input().split()))
    risk = list(map(int, input().split()))
    restrict = list(map(int, input().split()))
    
    max_reward = 0  # 最大收益
    rs = defaultdict(int)  # 存储最优方案
    
    for i in range(m):
        if risk[i] > x:
            continue
    
        # 只购买第 i 个产品
        k = min(restrict[i], n)
        if reward[i] * k > max_reward:
            rs.clear()
            rs[i] = k
            max_reward = reward[i] * k
    
        for j in range(i + 1, m):
            if risk[i] + risk[j] > x:
                continue
    
            cnti, cntj = restrict[i], restrict[j]
            if reward[i] > reward[j]:
                cnti = min(cnti, n)
                cntj = min(cntj, n - cnti)
            else:
                cntj = min(cntj, n)
                cnti = min(cnti, n - cntj)
    
            if reward[i] * cnti + reward[j] * cntj > max_reward:
                rs.clear()
                rs[i] = cnti
                rs[j] = cntj
                max_reward = reward[i] * cnti + reward[j] * cntj
    
    # 输出最优方案
    result = ' '.join(str(rs[i]) if i in rs else '0' for i in range(m))
    print(result)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    C++

    #include 
    #include 
    #include 
    #include 
    
    
    using namespace std;
    
    int main()
    {
        int m, n, x;
        cin >> m >> n >> x;
    
        // 用于存储投资回报率、风险和产品投资限制的数组
        vector<int> reward(m);
        vector<int> risk(m);
        vector<int> restrict(m);
    
        // 读取投资回报率
        for (int i = 0; i < m; i++) {
            cin >> reward[i];
        }
    
        // 读取风险值
        for (int i = 0; i < m; i++) {
            cin >> risk[i];
        }
    
        // 读取投资限制
        for (int i = 0; i < m; i++) {
            cin >> restrict[i];
        }
    
        int                     maxReward = 0;   // 最大收益
        unordered_map<int, int> rs;              // 存储最优投资数量的映射
    
        for (int i = 0; i < m; i++) {
            if (risk[i] > x) continue;
    
            // 只投资于产品 i
            int k = min(restrict[i], n);
            if (reward[i] * k > maxReward) {
                rs.clear();
                rs[i]     = k;
                maxReward = reward[i] * k;
            }
    
            for (int j = i + 1; j < m; j++) {
                if (risk[i] + risk[j] > x) continue;
    
                int cnti = restrict[i], cntj = restrict[j];
                if (reward[i] > reward[j]) {   // i,j 谁回报率高优先投谁
                    cnti = min(cnti, n);
                    cntj = min(cntj, n - cnti);
                } else {
                    cntj = min(cntj, n);
                    cnti = min(cnti, n - cntj);
                }
    
                if (reward[i] * cnti + reward[j] * cntj > maxReward) {
                    rs.clear();
                    rs[i]     = cnti;
                    rs[j]     = cntj;
                    maxReward = reward[i] * cnti + reward[j] * cntj;
                }
            }
        }
    
        // 输出每个产品的最优投资数量
        for (int i = 0; i < m; i++) {
            cout << rs[i] << " ";
        }
        cout << endl;
    
        return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77

    ‍❤️‍有考友通过专栏已经快速通过机考,都是原题哦~~ 💪

    📝 订阅 http://t.csdnimg.cn/lifXk

    🙏整理题解不易, 如果有帮助到您,请给点个赞 ‍❤️‍ 和收藏 ⭐,让更多的人看到。🙏🙏🙏

  • 相关阅读:
    第三次工业革命(二)
    【软件测试】测试人的我们,咋做一个如鱼得水的测试员?
    关于CASIO系列可编程计算器在公路施工测量中的应用
    UML软件哪个好?10款好用的UML工具和画图软件推荐!
    阿里云服务器经济型e实例规格云服务器性能介绍
    Jenkins从配置到实践(2022尚硅谷Jenkins学习笔记)
    ICS TRIPLEX T8310 自动化控制模块
    linux内核中内存反碎片技术
    C# Onnx Yolov8 Detect 手势识别
    时空预测 | 线性时空预测模型、图时空预测
  • 原文地址:https://blog.csdn.net/user_longling/article/details/136742412