题目描述
题目描述:
在一款虚拟游戏中生活,你必须进行投资以增强在虚拟游戏中的资产以免被淘汰出局。现有一家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 += 1
max_return = 0
max_status = ["0"] * number
max_return_risk = 0
for 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 j
other_return_product_index = i + j - max_return_product_index
max_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_return
max_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!愿你的代码如同畅快的音符,跳跃在键盘上,最后弹奏出一曲高分之歌。加油,你是技术舞台上的巨星!通过机试,就像是风轻云淡,轻轻松松就把高分收入囊中。祝愿你的编程之旅一路顺风,破风前行,每一行代码都是成功的注脚!🌈💻