当k和x都很大时,如何优化记忆消耗?
时间: 2024-10-06 22:03:11 浏览: 20
基于JAVA+SpringBoot+MySQL的校园台球厅人员与设备管理系统设计与实现.docx
当k和x都非常大时,直接使用三维动态规划会遇到内存限制的问题,因为dp数组会变得非常庞大。一种常见的优化方法是使用滚动数组(rolling array)或者称为“空间换时间”的策略。
滚动数组的思想是在计算过程中只保留必要的状态,每次只保存一个阶段的状态(比如上一阶段的某个部分)。在这个问题中,你可以只保留两个状态,例如dp[i][j]和dp[i][j+1],因为它们之间的状态转移只需要当前的和以及下一个可能的操作即可。对于宇宇的翻转,由于一次只能翻转一个数,所以可以在内层循环结束后更新这两个状态,而不是每次都创建新的dp[i][j][l]。
下面是使用滚动数组优化后的伪代码:
```cpp
std::vector<int> dp1(k + 1); // 存储阿鱼删除j个数后的情况
std::vector<int> dp2(x + 1); // 存储宇宇翻转l个数后的情况
for (int i = 1; i <= n; ++i) {
// 更新dp1(阿鱼)
dp1[0] = dp1[1]; // 保留旧的dp1[0]
for (int j = 1; j <= k; ++j) {
dp1[j] = std::max(dp1[j - 1], dp1[j - 1] + a[i - 1]);
if (j > 0) // 阿鱼删除,宇宇翻转
dp1[j] = std::max(dp1[j], dp1[j - 1] - a[i - 1]);
}
// 更新dp2(宇宇)
dp2[0] = dp2[1]; // 保留旧的dp2[0]
for (int l = 1; l <= x; ++l) {
dp2[l] = std::min(dp2[l - 1], dp2[l - 1] - a[i - 1]);
}
// 更新最终和
dp[i % 2] = std::max(dp[i % 2], dp1[k] + dp2[x]);
}
```
这样就从三维降低到了二维,极大地减少了存储需求。注意这里的`i % 2`用于保持交替地记录阿鱼和宇宇的最优解,因为他们的策略是交替影响和值的。
阅读全文