这是来自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 ....”?
我显然没有看到它!它应该只有一次 请帮忙搞清楚 - 我没有看到确切的额外呼叫在哪里发生!答案 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();
}