【发布时间】:2021-01-23 06:36:54
【问题描述】:
问题陈述:
给定两个数组
a和b,大小分别为n和m。这些数组中的所有数字都在 0 到 9 的范围内。让我们创建一个大小为n x m的矩阵,其中i行和j列中的值等于ai * 10^9 + bj。找到从正方形1,1到n,m的最大和的路径。您可以向前或向下移动。输入参数: 第一行包含
n和m(1第二行包含数组
a的值第三行包含数组
b的值输出 打印最大和
时间限制:1 秒
内存限制:512MB
例子:
输入:
7 4
0 7 1 7 6 7 6
4 1 9 7
输出:55000000068
我尝试用动态编程来解决这个问题,但是我的解决方案在O(n * m) 有效并且无法通过时间限制:
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
int main() {
int n, m; cin >> n >> m;
vector<uint64_t> a(n), b(m);
for(int i = 0; i < n; i++) {
int tmp;
cin >> tmp;
a[i] = tmp * 10e8;
}
for(int i = 0; i < m; i++) cin >> b[i];
vector<uint64_t> dp(m);
dp[0] = a[0] + b[0];
for (int i = 1; i < m; i++)
dp[i] = dp[i-1] + a[0] + b[i];
for (int i = 1; i < n; ++i) {
for(int j = 0; j < m; ++j) {
if (j == 0)
dp[j] = dp[j] + a[i] + b[j];
else
dp[j] = max(dp[j], dp[j-1]) + a[i] + b[j];
}
}
cout << dp.back() << endl;
return 0;
}
【问题讨论】:
-
我不确定,但是,使用带有记忆的递归函数可能会解决它。这是因为在递归函数中,您不会填充整个矩阵。
-
如果您可以向前或向下移动,这是否意味着您需要两个索引来获得最佳解决方案?例如,正方形 (2,3) 可以从 (1,3) 或 (2,2) 到达
-
@HikmatFarhat someval 是什么意思?我在我的解决方案中使用了一维数组,因为使用二维数组我们不会超过内存限制
-
请注意,这个问题不是对称的:通过停留在大数字的行上,您可以获得更多“点”。那么问题是“你什么时候从一大排跳到下一排”。
-
旁白:
int tmp; cin >> tmp; a[i] = tmp * 10e8;可能会遇到精度问题,因为乘法不使用 64 位整数数学。建议uint64_t tmp;OTOH,也许可以使用限制性 0-9tmp值。
标签: c++ algorithm dynamic-programming