简单的递归/ dp - 帮助跟踪

时间:2013-12-30 18:59:52

标签: c++ debugging recursion dynamic-programming

这是来自CodeChef的dp教程,我正在跟踪它。

详细信息:当我输入if子句时 - 我打印“STEP 1”/ step2 / step3。 该计划运作良好。

#include <iostream>
#include <string.h>
#include <stdio.h>
using namespace std ;
#define min(a,b) ( (a) < (b) ? (a) : (b))

int memo[10 + 1] ;
void reset_memo()
{
    cout << endl ;
    cout << "RESETTING MEMO" << endl ;
    for (int i = 0 ; i < 11 ; i++) {
        memo[i] = -1 ;
    }
}

int getMinSteps(int n)
{
    cout << "======current n : " << n <<  " ===============" << endl ;
    if (n == 1) {
        cout << "BASE CASE n = 1 and returning 0..." << endl ;
        return 0;
    }  // base case

    if (memo[n] != -1) {
        return memo[n];
    } // we have solved it already :)

    cout << "STEP 1 " << endl ;
    int r = 1 + getMinSteps(n - 1);    // '-1' step .  'r' will contain the optimal answer finally

    if (n % 2 == 0) {
        cout << " STEP 2: "  << endl ;
        r = min(r , 1 + getMinSteps(n / 2)) ;
    }  //  '/2' step

    if (n % 3 == 0) {
        cout << " STEP 3: "   << endl ;
        r =  min(r , 1 + getMinSteps(n / 3)) ;
    }  //  '/3' step

    memo[n] = r ;  // save the result. If you forget this step, then its same as plain recursion.
    return r;
}

我花了5个小时试图了解一个小细节:

输出:

重播备忘录

输入下一个号码

2

===============当前n 2 ===============

第1步:

===============当前n 1 ===============

BASE CASE n = 1并返回0 ...

第2步:

===============当前n 1 ===============

BASE CASE n = 1并返回0 ...

===============当前n 1 ===============

BASE CASE n = 1并返回0 ...

结果1

重播备忘录 输入下一个号码


为什么称黑色突出显示最后一段代码“BASE CASE ....”?

我显然没有看到它!它应该只有一次 请帮忙搞清楚 - 我没有看到确切的额外呼叫在哪里发生!

1 个答案:

答案 0 :(得分:1)

我在调试器下测试了程序,min( )导致getMinSteps(n / 2)被调用两次。这是因为您使用b两次#define min(a,b) ( (a) < (b) ? (a) : (b))导致副作用的宏定义。尝试使用std:min代替。

以下是案例n % 2 == 0

的另一种解决方法
#include <iostream>
#include <string.h>
#include <stdio.h>
using namespace std ;
#define min(a,b) ( (a) < (b) ? (a) : (b))

int memo[10 + 1] ;



void reset_memo()
{
    cout << endl ;
    cout << "RESETTING MEMO" << endl ;
    for (int i = 0 ; i < 11 ; i++) {
        memo[i] = -1 ;
    }
}

int getMinSteps(int n)
{
    cout << "======current n : " << n <<  " ===============" << endl ;
    if (n == 1) {
        cout << "BASE CASE n = 1 and returning 0..." << endl ;
        return 0;
    }  // base case

    if (memo[n] != -1) {
        return memo[n];
    } // we have solved it already :)

    cout << "STEP 1 " << endl ;
    int r = 1 + getMinSteps(n - 1);    // '-1' step .  'r' will contain the optimal answer finally

    if (n % 2 == 0) {
        cout << " STEP 2: "  << endl ;
        int v =  getMinSteps(n / 2); // <--- so getMinSteps will be called only once!
        r = min(r , 1 + v) ;
    }  //  '/2' step

    if (n % 3 == 0) {
        cout << " STEP 3: "   << endl ;
        r =  min(r , 1 + getMinSteps(n / 3)) ;
    }  //  '/3' step

    memo[n] = r ;  // save the result. If you forget this step, then its same as plain recursion.
    return r;
}

int main(){
    reset_memo();
    getMinSteps(2);
    getchar();
    getchar();

}