Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/powershell/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如果将记忆添加到递归中,则解决方案错误_C++_Recursion_Dynamic_C++14_Memoization - Fatal编程技术网

C++ 如果将记忆添加到递归中,则解决方案错误

C++ 如果将记忆添加到递归中,则解决方案错误,c++,recursion,dynamic,c++14,memoization,C++,Recursion,Dynamic,C++14,Memoization,我创建了一个DP程序,但问题是,当我不使用备忘录时,我得到了正确的答案。一旦我引入备忘录,我就开始对一些问题给出错误的答案 这里是C++ 14中的代码,注释< < /p>关闭了记忆。 #include <iostream> #include <math.h> #include<algorithm> using namespace std; int max_Number_of_turns; int dp[9999][1000]; int changeTheDi

我创建了一个DP程序,但问题是,当我不使用备忘录时,我得到了正确的答案。一旦我引入备忘录,我就开始对一些问题给出错误的答案

这里是C++ 14中的代码,注释< < /p>关闭了记忆。

#include <iostream>
#include <math.h>
#include<algorithm>

using namespace std;
int max_Number_of_turns;
int dp[9999][1000];
int changeTheDigit(int n, int d) {
    int rem = n % (int) (pow(10, 4 - d));
    n /= (pow(10, 4 - d));
    int x = n % 10;
    n /= 10;
    if (x == 9) x = 0;
    else x = x + 1;
    n = n * (10) + x;
    n = n * (pow(10, 4 - d)) + rem;
    return n;
}

int minMax(int n, int t) {
    int ans =0;
    //if(dp[n][t]>=0) { return dp[n][t];}
    if (t > max_Number_of_turns) return n;

    int N;
    for (int i = 0; i < 4; i++) {
        N = changeTheDigit(n, i + 1);
        if (t % 2 == 0) {
            //Manish chance
            if(ans==0) ans=minMax(N, t+1);
            else ans = min(ans, minMax(N, t + 1));
        } else {
            //Nitish Chance
            ans = max(ans, minMax(N, t + 1));
        }
    }
    //cout << ans << endl;
    dp[n][t]=ans;
    return ans;
}

using namespace std;

int main() {
    int T, N, M;
    cin >> T;
    while (T--) {
        cin >> N >> M;
        max_Number_of_turns=M;
        for(int i=0;i<9999;i++)
            for(int j=0;j<1000;j++)
                dp[i][j]=-1;
        if(minMax(N,1)>N){
            cout << "Nitish" << endl;
        }
        else{
            cout << "Manish" << endl;
        }
    }
    return 0;
}
我的代码会对一些问题给出错误的答案 例如,让我们考虑输入

1
4569 12
原始正确的解决方案是Manish 但如果我打开记忆,我的解决方案是尼蒂什

你能告诉我我做错了什么吗

另外,一个有趣的事实是,如果

if(dp[n][t]>=0) { return dp[n][t];}


然后一切正常

您的问题是没有检查n和/或t的值,因此可能会导致数组出现越界问题。您可以看到,如果在minMax函数的开头插入以下内容:

if (n < 0 || n >= 9999) cout << "n invalid at " << n << '\n';
if (t < 0 || t >= 1000) cout << "t invalid at " << t << '\n';
要解决此问题,您只需确保只有在存储空间足够时才使用备忘录,首先是在检查值时:

if (n >= 0 && n < 9999 && t >= 0 && t < 1000 && dp[n][t] >= 0)
    return dp[n][t];
if (n >= 0 && n < 9999 && t >= 0 && t < 1000)
    dp[n][t] = ans;
第二,在存储值时:

if (n >= 0 && n < 9999 && t >= 0 && t < 1000 && dp[n][t] >= 0)
    return dp[n][t];
if (n >= 0 && n < 9999 && t >= 0 && t < 1000)
    dp[n][t] = ans;

一旦我引入DP,我就开始得到一些问题的错误答案-也许你实现的不正确?为什么不使用这些代码并使用你的调试器呢?这段代码是来自那些在线编码网站的吗?在那里,您使用的是他们的嵌入式编译器,而不是您自己的编译器,这样您就可以调试代码了?如果是这样的话,找一个编译器,把你的代码,编译它,调试它。您有测试用例和它产生的输出-我们不需要为您做调试工作。minMax偶尔被调用为n>=9999,因此dp被越界访问,程序表现出未定义的行为。@VishalSingh并证明Igor Tandetnik所说的。使用std::vector和at表明您已经越界了。这表明,在线编码网站不教如何诊断问题,甚至编写C++代码,在那里可以很容易地诊断问题。如果您不使用原始数组,而是使用std::vector,您将有机会自己轻松找到问题。@VishalSingh。问题是,您使用的是原始数组,如果您越界,不能保证会发生任何不好的事情,但您永远不会知道您越界了。如果使用std::vector,则可以保证,如果使用at而不是[]访问超出边界的元素,将引发异常。当你真正知道如何编写好的C++代码,或者至少知道如何编写代码来揭示bug时,看看它们的区别。错误就会显露出来。在线编码网站并不强调这一点。
if (n >= 0 && n < 9999 && t >= 0 && t < 1000)
    dp[n][t] = ans;