题目描述 小 W 要搬家了,他面前有 𝑛 n 本书,每本书带走与不带走都各自有一个收益。 他最多能带走 𝑚 m 本书,请帮小 W 求出他能取得的最大收益。 输入格式 第一行两个整数 𝑛 , 𝑚 n,m。 第二行 𝑛 n 个整数 𝑎 𝑖 a i ,表示带走第 𝑖 i 本书的收益。 第三行 𝑛 n 个整数 𝑏 𝑖 b i ,表示不带走第 𝑖 i 本书的收益。 输出格式 一行一个整数,表示最大收益。 输入输出样例 输入#1 复制 输出#1 复制 输入#2 复制 输出#2 复制 说明/提示 对于 30 % 30% 的数据, 𝑛 ≤ 20 n≤20。 对于 60 % 60% 的数据, 𝑛 ≤ 2025 n≤2025。 另有 10 % 10% 的数据, 𝑚 = 1 m=1。 对于 100 % 100% 的数据, 0 ≤ 𝑚 ≤ 𝑛 ≤ 5 × 1 0 5 . ∣ 𝑎 𝑖 ∣ , ∣ 𝑏 𝑖 ∣ ≤ 1 0 9 0≤m≤n≤5×10 5 .∣a i ∣,∣b i ∣≤10 9 。C++
时间: 2025-09-06 13:44:15 AIGC 浏览: 7
该问题可以使用动态规划来解决。定义一个三维数组 `dp[i][j][k]`,其中 `i` 表示考虑前 `i` 本书,`j` 表示已经选择了 `j` 本书,`k` 表示当前的收益状态。状态转移方程需要根据是否选择第 `i` 本书来更新。
以下是实现该算法的 C++ 代码:
```cpp
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int maxProfit(int n, int m, vector<int>& takeProfit, vector<int>& notTakeProfit) {
// dp[i][j] 表示考虑前 i 本书,选择了 j 本书时的最大收益
vector<vector<int>> dp(n + 1, vector<int>(m + 1, 0));
for (int i = 1; i <= n; ++i) {
for (int j = 0; j <= m; ++j) {
// 不选择第 i 本书
dp[i][j] = dp[i - 1][j] + notTakeProfit[i - 1];
if (j > 0) {
// 选择第 i 本书
dp[i][j] = max(dp[i][j], dp[i - 1][j - 1] + takeProfit[i - 1]);
}
}
}
int maxProfit = 0;
for (int j = 0; j <= m; ++j) {
maxProfit = max(maxProfit, dp[n][j]);
}
return maxProfit;
}
int main() {
int n, m;
cout << "请输入书的总数 n 和最多能带走的书的数量 m: ";
cin >> n >> m;
vector<int> takeProfit(n);
vector<int> notTakeProfit(n);
cout << "请依次输入每本书带走的收益: ";
for (int i = 0; i < n; ++i) {
cin >> takeProfit[i];
}
cout << "请依次输入每本书不带走的收益: ";
for (int i = 0; i < n; ++i) {
cin >> notTakeProfit[i];
}
int result = maxProfit(n, m, takeProfit, notTakeProfit);
cout << "能取得的最大收益是: " << result << endl;
return 0;
}
```
### 代码解释
1. **`maxProfit` 函数**:该函数接受书的总数 `n`、最多能带走的书的数量 `m`、每本书带走的收益数组 `takeProfit` 和每本书不带走的收益数组 `notTakeProfit` 作为参数。使用二维数组 `dp` 来记录状态,通过两层循环遍历所有书和选择的数量,更新 `dp` 数组的值。最后,遍历 `dp[n]` 数组,找出最大收益。
2. **`main` 函数**:读取用户输入的书的总数 `n`、最多能带走的书的数量 `m`、每本书带走的收益和每本书不带走的收益。调用 `maxProfit` 函数计算最大收益,并输出结果。
### 复杂度分析
- **时间复杂度**:$O(n \times m)$,其中 $n$ 是书的总数,$m$ 是最多能带走的书的数量。
- **空间复杂度**:$O(n \times m)$,主要用于存储 `dp` 数组。
阅读全文