最大矩阵成本路径
maximum matrix cost path,
我正试图通过动态编程来解决这个问题:
您将得到一个由n行和m列组成的矩阵。每个元素都有一个数字兔子停留在左上角元素。
计算最大和,使兔子到达底部元素只允许移动两个:
向右两步,向下一步(x+2,y+1)
向下两步,向右一步(x+1,y+2);输入:
第一行包含两个自然数n和m(1≤n、 m≤103)——矩阵的行和列的数量。
接下来的n行包含m数字——矩阵的值元素。
左上角坐标为(1,1),右下角坐标为角的–(n,m)。
输出:
使兔子到达右下角的最大总和。如果无法到达右下角,则输出
-
输入1:
3 3 5 0 0 0 1 2 1 0 1
输出1:
-
输入2:
4 4 5 2 1 0 1 0 0 0 2 1 3 0 0 0 1 7
输出2:
13
这是我试图开发的代码:
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <algorithm>
using namespace std;
void findMaxSum(int *a[], int r, int c)
{
int **res = new int*[r];
for (int i = 0; i < r; i++) {
res[i] = new int[c];
for (int j = 0; j < c; j++)
res[i][j] = -1;
}
for (int i = 0; i < r-1; i++) {
for (int j = i; j < c-1; j++) {
res[i + 1][j + 2] = max(a[i][j] + a[i + 1][j + 2], res[i + 1][j + 2]);
res[i + 2][j + 1] = max(a[i][j] + a[i + 2][j + 1], res[i + 2][j + 1]);
}
}
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++)
cout << res[i][j] << " ";
cout << endl;
}
delete[] res;
}
int main() {
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
int r, c;
cin >> r >> c;
int **a = new int*[r];
for (int i = 0; i < r; i++) {
a[i] = new int[c];
}
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++)
cin >> a[i][j];
}
findMaxSum(a, r, c);
delete[] a;
return 0;
}
这是一种方法吗?循环内部的计算是否正确?
首先要意识到,这是更常见问题的变体,其中有效的"移动"是"右"answers"下"。它可以映射到它。
如果你想象出有效移动可以到达的点,你就会在矩阵中得到这样的模式:
x - - - - - - - -
- - x - - - - - -
- x - - x - - - -
- - - x - - x - -
- - x - - x - - x
- - - - x - - x -
- - - x - - x - -
- - - - - x - - x
所以实际上,许多矩阵值甚至没有发挥作用——它们是无法达到的。如果我们还去除了无法达到目标的地方的斑点,那么我们就得到了这个。我还用一些不同的字母来突出显示一个属性:
x - - - - - - - -
- - x - - - - - -
- y - - x - - - -
- - - y - - x - -
- - z - - y - - -
- - - - z - - y -
- - - - - - z - -
- - - - - - - - z
如果它有一个"x",则只能通过(+2,+1)类型的移动到达该点。在有"y"的地方,需要一种(+1,+2)类型的移动,在有"z"的地方需要其中两种。
这是一个可以转换为以下形状的形状:
x x x x
y y y y
z z z z
这样翻译问题,并在该配置中解决它,会很有趣。
我不会在这里追求这个想法。
您的代码当前缺少关于何时输出-
的测试。
我们需要测试是否可以到达目标细胞。您可以看到,如果某个点的x和y坐标之和(基于零)不是3的倍数,则无法到达该点。还有一些地方的总和是3的倍数,但仍然遥不可及。其中一个坐标至少是另一个坐标的两倍(标有星号):
x - - * - - * - -
- - x - - * - - *
- y - - x - - * -
* - - y - - x - -
- - z - - y - - -
- * - - z - - y -
* - - - - - z - -
- - * - - - - - z
所以你应该把这一行添加到你的代码中:
if ((r+c) % 3 != 2 || r*2 < c || c*2 < r) {
cout << "-";
return;
}
(r+c) % 3 != 2
是从(r-1 + c-1) % 3 != 0
导出的,而r*2 < c
是从差为1的(r-1)*2 < (c-1)*2
导出的,这在给定第一个条件的情况下是不相关的。
对于初始化部分:无需使用-1值初始化res
矩阵。无论如何,你都不想在计算中加入-1。您需要避免依赖此类值。相反,必须初始化动态编程工作的起点:
res[0][0] = a[0][0];
然后,对于实际的"引导":我首先只使用一种类型的移动,并向该方向累积成本:
for (int i = 2, j = 1; (r-i)*2 > c-j; i+=2, j++) {
res[i][j] = res[i-2][j-1] + a[i][j];
}
请注意,循环的停止条件消除了目标无法到达的地方的斑点。
在另一个方向上也这样做:
for (int i = 1, j = 2; (c-j)*2 > r-i; i++, j+=2) {
res[i][j] = res[i-1][j-2] + a[i][j];
}
现在您已经为主要的动态编程部分设置了"外部边界"。其他有效点将始终有2个可能的点可供选择。因此,通过从以下两个点中选择最大值来选择所有其他路径:
for (int i = 2, j = 1; (r-i)*2 > c-j; i+=2, j++) {
for (int m = i + 1, n = j + 2; (c-n)*2 > r-m; m++, n += 2) {
res[m][n] = max(res[m-1][n-2], res[m-2][n-1]) + a[m][n];
}
}
并最终输出结果:
cout << res[r-1][c-1];
注意:我更希望函数返回该值,并让main
执行所有I/O。
以下是要解决的问题:
-
数组元素的越界访问。仔细查看要访问的元素,以及循环边界是什么。最简单的解决方法是相应地加宽阵列。
-
数组元素的初始化错误。注意,
-1
(不可达的正方形)加上10
是9
,它看起来像是一个有效值。最简单的修复方法是使用负无穷大(这是max
操作的适当中性元素)而不是-1
进行初始化。一个好的负无穷大的默认值是INT_MIN / 2
。
这两个可能足以使程序正常工作。
以下是未来需要考虑的要点:
-
数组构造。首先,对于相应的
new
操作,没有足够的delete
操作,因此程序会泄漏内存。话虽如此,我不明白为什么在C++中需要对多维纯数组进行繁琐的内存管理,而vector
可以更方便地进行同样的管理。与vector
s相关的轻微放缓并不能证明在其他97%的情况下遭受整类错误的折磨是合理的。 -
提问。问题是这样的:"这是问题所在,这是代码中的解决方案"。缺少的步骤是用文本解释代码的含义。因此,不熟悉问题和解决方案的人将很难从一开始就真正理解你的问题,并理所当然地认为这是一个形式不正确的问题。此外,您可能会发现,在查看代码时,解决缺失的步骤当然会在没有任何交互的情况下回答一些问题:)(请参阅橡皮鸭调试)。
- 如何将更多文件夹添加到c++include路径
- 带有特殊路径部分的"std::filesystem::weakly_canonical"失败
- C++A*算法并不总是在路径中具有目标节点
- 从函数角度看ID到文件路径的内部与外部映射
- boost xml parsingl将xml的路径作为变量发送
- 对于MacOS上的G++,如何添加默认的include目录/usr/local/include和默认的库搜索路径/usr
- 如何使用cppcheck处理半相对包含路径
- 在C++中设置基于操作系统的文件路径
- 基于编译器选项的编译二进制路径
- 按边长度递归搜索图中所有可行路径
- 使用变量值作为 PlaySound 中的路径
- 如何转换真实路径 CString c++
- 从 GUID 获取 USB 卷路径
- 查找 GCD:并非所有控制路径都返回值
- C++17 文件系统::remove_all 带有通配符路径
- 在带有尾部斜杠的路径上返回 std::filesystem::create_directories() 的值
- 获取当前正在运行的 exe 名称(不是路径)
- 如何从 Skia 路径几何体中获取网格?
- CMake 错误"源似乎不包含 CMakeLists.txt",路径/库连接问题
- VS Code C++:不准确的系统包括路径错误(wchar.h,boost/lambda/lambda.hpp)