题目描述
题目描述:
在一款虚拟游戏中生活,你必须进行投资以增强在虚拟游戏中的资产以免被淘汰出局。现有一家Bank,它提供有若干理财产品m,风险及投资回报不同,你有N(元)进行投资,能接受的总风险值为X。
你要在可接受范围内选择最优的投资方式获得最大回报。
说明:
在虚拟游戏中,每项投资风险值相加为总风险值;
在虚拟游戏中,最多只能投资2个理财产品;
在虚拟游戏中,最小单位为整数,不能拆分为小数;
投资额回报率=投资回报
输入描述:
第一行:产品数(取值范围[1, 20]),总投资额(整数,取值范围[1, 10000]),可接受的总风险(整数,取值范围[1, 200])
第二行:产品投资回报率序列,输入为整数,取值范围[1,60]
第三行:产品风险值序列,输入为整数,取值范围[1,100]
第四行:最大投资额度序列,输入为整数,取值范围[1,10000]
输出描述:
每个产品的投资额序列
补充说明:
在虚拟游戏中,每项投资风险值相加为总风险值;
在虚拟游戏中,最多只能投资2个理财产品;
在虚拟游戏中,最小单位为整数,不能拆分为小数;
投资额回报率=投资回报
示例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
解题思路
-
输入处理: 读取输入,获取产品数、总投资额、可接受的总风险值以及各项指标的序列。
-
动态规划定义: 定义一个二维数组
dp
,其中dp[i][j]
表示在前i
个产品中选择不超过j
总投资额的情况下,能够达到的最小总风险值。 -
状态转移方程: 对于第
i
个产品,有两个选择:不投资或者投资。若选择不投资,则dp[i][j] = dp[i-1][j]
;若选择投资,则dp[i][j] = dp[i-1][j-investment[i]] + risk[i]
,其中investment[i]
为第i
个产品的投资额,risk[i]
为第i
个产品的风险值。 -
递推填表: 从
i=1
到n
,从j=0
到total_investment
,根据状态转移方程填充动态规划表。 -
构建最优解: 从填充好的动态规划表中反向追溯,得到最优解,即投资额序列。
-
输出结果: 输出每个产品的投资额序列。
这样的动态规划方法能够有效地找到在总投资额和总风险值限制下,获取最大回报的投资方式。
题解代码
理解你的需求,我会为Python、Java、C/C++和JavaScript分别提供相应的题解代码。
Python题解代码
number, N, X = map(int, input().split())
return_list = list(map(int, input().split()))
risk_list = list(map(int, input().split()))
max_cost_list = list(map(int, input().split()))return_list.append(0)
risk_list.append(0)
max_cost_list.append(0)
number += 1max_return = 0
max_status = ["0"] * number
max_return_risk = 0for i in range(number):for j in range(i + 1, number):if risk_list[i] + risk_list[j] <= X:max_return_product_index = i if return_list[i] > return_list[j] else jother_return_product_index = i + j - max_return_product_indexmax_return_cost = min(N, max_cost_list[max_return_product_index])other_return_cost = min(N - max_return_cost, max_cost_list[other_return_product_index])cur_return = (return_list[max_return_product_index] * max_return_cost+ return_list[other_return_product_index] * other_return_cost)if cur_return > max_return:max_return = cur_returnmax_return_risk = risk_list[i] + risk_list[j]max_dict = {max_return_product_index: max_return_cost,other_return_product_index: other_return_cost,}for k in range(number):max_status[k] = str(max_dict.get(k, 0))
print(" ".join(max_status[:-1]))
Java题解代码
import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);int number = scanner.nextInt();int N = scanner.nextInt();int X = scanner.nextInt();int[] returnList = new int[number];int[] riskList = new int[number];int[] maxCostList = new int[number];for (int i = 0; i < number; i++) {returnList[i] = scanner.nextInt();}for (int i = 0; i < number; i++) {riskList[i] = scanner.nextInt();}for (int i = 0; i < number; i++) {maxCostList[i] = scanner.nextInt();}int[] maxReturnStatus = getMaxReturnStatus(number, N, X, returnList, riskList, maxCostList);for (int i = 0; i < number; i++) {System.out.print(maxReturnStatus[i] + " ");}}private static int[] getMaxReturnStatus(int number, int N, int X, int[] returnList, int[] riskList, int[] maxCostList) {number++;int[] returnListExtended = new int[number];int[] riskListExtended = new int[number];int[] maxCostListExtended = new int[number];System.arraycopy(returnList, 0, returnListExtended, 0, returnList.length);System.arraycopy(riskList, 0, riskListExtended, 0, riskList.length);System.arraycopy(maxCostList, 0, maxCostListExtended, 0, maxCostList.length);returnListExtended[number - 1] = 0;riskListExtended[number - 1] = 0;maxCostListExtended[number - 1] = 0;int maxReturn = 0;int maxReturnRisk = 0;int[] maxStatus = new int[number];for (int i = 0; i < number; i++) {for (int j = i + 1; j < number; j++) {if (riskListExtended[i] + riskListExtended[j] <= X) {int maxReturnProductIndex = (returnListExtended[i] > returnListExtended[j]) ? i : j;int otherReturnProductIndex = i + j - maxReturnProductIndex;int maxReturnCost = Math.min(N, maxCostListExtended[maxReturnProductIndex]);int otherReturnCost = Math.min(N - maxReturnCost, maxCostListExtended[otherReturnProductIndex]);int curReturn = returnListExtended[maxReturnProductIndex] * maxReturnCost+ returnListExtended[otherReturnProductIndex] * otherReturnCost;if (curReturn > maxReturn) {maxReturn = curReturn;maxReturnRisk = riskListExtended[i] + riskListExtended[j];for (int k = 0; k < number; k++) {maxStatus[k] = (k == maxReturnProductIndex) ? maxReturnCost: (k == otherReturnProductIndex) ? otherReturnCost : 0;}}}}}return maxStatus;}
}
C/C++题解代码
#include <iostream>
#include <vector>using namespace std;vector<int> getMaxReturnStatus(int number, int N, int X, vector<int> returnList, vector<int> riskList, vector<int> maxCostList) {number++;returnList.push_back(0);riskList.push_back(0);maxCostList.push_back(0);int maxReturn = 0;int maxReturnRisk = 0;vector<int> maxStatus(number, 0);for (int i = 0; i < number; i++) {for (int j = i + 1; j < number; j++) {if (riskList[i] + riskList[j] <= X) {int maxReturnProductIndex = (returnList[i] > returnList[j]) ? i : j;int otherReturnProductIndex = i + j - maxReturnProductIndex;int maxReturnCost = min(N, maxCostList[maxReturnProductIndex]);int otherReturnCost = min(N - maxReturnCost, maxCostList[otherReturnProductIndex]);int curReturn = returnList[maxReturnProductIndex] * maxReturnCost+ returnList[otherReturnProductIndex] * otherReturnCost;if (curReturn > maxReturn) {maxReturn = curReturn;maxReturnRisk = riskList[i] + riskList[j];fill(maxStatus.begin(), maxStatus.end(), 0);maxStatus[maxReturnProductIndex] = maxReturnCost;maxStatus[otherReturnProductIndex] = otherReturnCost;}}}}return maxStatus;
}int main() {int number, N, X;cin >> number >> N >> X;vector<int> returnList(number);vector<int> riskList(number);vector<int> maxCostList(number);for (int i = 0; i < number; i++) {cin >> returnList[i];}for (int i = 0; i < number; i++) {cin >> riskList[i];}for (int i = 0; i < number; i++) {cin >> maxCostList[i];}vector<int> maxReturnStatus = getMaxReturnStatus(number, N, X, returnList, riskList, maxCostList);for (int i = 0; i < number; i++) {cout << maxReturnStatus[i] << " ";}return 0;
}
JavaScript题解代码
function getMaxReturnStatus(number, N, X, returnList, riskList, maxCostList) {number++;returnList.push(0);riskList.push(0);maxCostList.push(0);let maxReturn = 0;let maxReturnRisk = 0;const maxStatus = new Array(number).fill(0);for (let i = 0; i < number; i++) {for (let j = i + 1; j < number; j++) {if (riskList[i] + riskList[j] <= X) {const maxReturnProductIndex = (returnList[i] > returnList[j]) ? i : j;const otherReturnProductIndex = i + j - maxReturnProductIndex;const maxReturnCost = Math.min(N, maxCostList[maxReturnProductIndex]);const otherReturnCost = Math.min(N - maxReturnCost, maxCostList[otherReturnProductIndex]);const curReturn = returnList[maxReturnProductIndex] * maxReturnCost+ returnList[otherReturnProductIndex] * otherReturnCost;if (curReturn > maxReturn) {maxReturn = curReturn;maxReturnRisk = riskList[i] + riskList[j];maxStatus.fill(0);maxStatus[maxReturnProductIndex] = maxReturnCost;maxStatus[otherReturnProductIndex] = otherReturnCost;}}}}return maxStatus;
}const readline = require('readline');
const rl = readline.createInterface({input: process.stdin,output: process.stdout
});rl.question('', (input) => {const inputs = input.split(' ');const number = parseInt(inputs[0]);const N = parseInt(inputs[1]);const X = parseInt(inputs[2]);rl.question('', (input) => {const returnList = input.split(' ').map(Number);rl.question('', (input) => {const riskList = input.split(' ').map(Number);rl.question('', (input) => {const maxCostList = input.split(' ').map(Number);const maxReturnStatus = getMaxReturnStatus(number, N, X, returnList, riskList, maxCostList);console.log(maxReturnStatus.join(' '));rl.close();});});});
});
代码OJ评判结果
通过测试点
代码讲解
Python题解代码讲解
-
输入处理: 通过
input()
读取产品数number
、总投资额N
、可接受总风险X
以及各项指标序列。 -
数据初始化: 将输入的指标序列添加一个0,用于处理边界情况。同时,增加
number
变量。 -
遍历组合: 使用两层循环遍历所有产品组合,计算它们的总风险和是否符合可接受风险。
-
判断最大回报: 对于符合条件的组合,计算它们的回报,并比较是否超过之前的最大回报。若是,则更新最大回报及相应的投资组合。
-
输出结果: 输出得到的最优投资组合的投资额序列。
Java题解代码讲解
-
输入处理: 使用
Scanner
读取产品数number
、总投资额N
、可接受总风险X
以及各项指标序列。 -
数据初始化: 将输入的指标序列添加一个0,用于处理边界情况。同时,增加
number
变量。 -
调用函数: 调用
getMaxReturnStatus
函数,传递输入参数,并获取最优投资组合的投资额序列。 -
输出结果: 输出得到的最优投资组合的投资额序列。
C/C++题解代码讲解
-
输入处理: 使用
cin
读取产品数number
、总投资额N
、可接受总风险X
以及各项指标序列。 -
数据初始化: 将输入的指标序列添加一个0,用于处理边界情况。同时,增加
number
变量。 -
调用函数: 调用
getMaxReturnStatus
函数,传递输入参数,并获取最优投资组合的投资额序列。 -
输出结果: 输出得到的最优投资组合的投资额序列。
JavaScript题解代码讲解
-
输入处理: 使用Node.js的
readline
模块逐行读取输入,获取产品数number
、总投资额N
、可接受总风险X
以及各项指标序列。 -
数据初始化: 将输入的指标序列添加一个0,用于处理边界情况。同时,增加
number
变量。 -
调用函数: 调用
getMaxReturnStatus
函数,传递输入参数,并获取最优投资组合的投资额序列。 -
输出结果: 输出得到的最优投资组合的投资额序列。
寄语
🚀✨ 朋友,希望你的华为OD机试就像是一场轻松的技术party!愿你的代码如同畅快的音符,跳跃在键盘上,最后弹奏出一曲高分之歌。加油,你是技术舞台上的巨星!通过机试,就像是风轻云淡,轻轻松松就把高分收入囊中。祝愿你的编程之旅一路顺风,破风前行,每一行代码都是成功的注脚!🌈💻