实现动态规划算法问题C++和Python时,结果有什么不同



在《绝地求生》中,有三个等级的盔甲和防弹衣,每个等级记录为1,2,3。每次你只能拿起你没有的东西,或者将低级别的装备升级到高级别时,你都会问有多少从零到"护甲三级护甲三级"的升级路线?当前状态由有序数量的对(防弹衣、盔甲(表示,作为升级策略,这两个对的值都为0-3,例如(0,0(->(0,1(->(0,3(->(3,3(。

理论上它是一个4*4数组,我想知道为什么python 4*4阵列可以实现,但c++必须写成int[4][4],即5*5数组的结果是对的,int[3][3]计算错误?(结果是最后一个元素,即106(

python:

dp = [[1,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]]
for i in range(4):
for j in range(4):
for m in range(j):
dp[i][j] += dp[i][m]
for m in range(i):
dp[i][j] += dp[m][j]
dp

输出:106(正确答案(c++:

#include<iostream>
int dp[3][3];
int main (){
dp[0][0] = 1;
for (int i = 0; i <= 3; i++){
for (int j = 0; j <= 3; j++){
for (int m = 0; m < i; m++)
dp[i][j] += dp[m][j];
for (int m = 0; m < j; m++)
dp[i][j] += dp[i][m];
}
}
std::cout<<dp[3][3]<<std::endl;
}

输出:1495(哇!但我不知道为什么?为什么c++中的输出是错误的?(

好的,找到了。你的问题是,你使用的是一个3x3大小的数组,就像它是4x4大小的一样。
一个工作版本:

#include<iostream>
int dp[4][4];
int main ()
{
dp[0][0] = 1;
for (int i = 0; i < 4; i++){
for (int j = 0; j < 4; j++){
for (int m = 0; m < j; m++)
dp[i][j] += dp[i][m];
for (int m = 0; m < i; m++)
dp[i][j] += dp[m][j];
}
}
std::cout<<dp[3][3]<<std::endl; 
}

CCD_ 1至CCD_。这样,上面的代码就可以工作了
否则,您将越界访问数组,这是未定义的行为。1495只是编译器如何解释代码的结果,但由于它是UB,任何结果都是有效的。这就是UB的欺骗性——它通常看起来像是做了一些合理的事情,让它看起来像是你算法中的一个错误,而事实并非如此
我在试验时做了一些进一步的小改动。其中一个是将两个内部循环切换为循环,但这一个不是必须的。我还将<= 3更改为< 4,因为这是一种更常见的样式,但显然也不是必需的。

对于未来,熟悉使用调试器,或者在两个步骤之间打印出结果。如果你有工作的phyton代码,你可以在那里做同样的事情,然后比较两个程序的行为。然而,请注意,在你的情况下,结果可能看起来很奇怪——我是在实验时这样做的,结果很有趣,看http://www.cpp.sh/8aufco。变量i运行到257,尽管循环将其约束为3。我不知道为什么会这样——只是UB的结果。

您可能想考虑将原始数组更改为std::vectorstd::array,但我暂时不考虑
您的main应该将return 0;作为一种良好的做法,尽管它可以正常工作。
您不应该像使用dp那样在C++中使用任何全局变量。只需在您的主控室内(或以后使用它的任何地方(声明即可。全局变量是一个容易产生错误的来源(注意常量是可以的(。

最新更新