【发布时间】:2015-08-15 07:47:36
【问题描述】:
我正在尝试学习动态编程 (DP) 的基础知识,并浏览了一些我可以获得的在线资源,例如...
- What is dynamic programming?
- Good examples, articles, books for understanding dynamic programming
- Tutorial for Dynamic Programming
- Dynamic Programming – From Novice to Advanced --(我无法正确理解(即如何使用 DP 解决问题))
直到现在我才明白
动态问题几乎与 递归只是有区别(这赋予了它已知的力量 为)
即存储我们获得的价值或解决方案并再次使用它来寻找下一个解决方案
例如:
根据codechef的解释
问题:最小步数
问题陈述:对于一个正整数,您可以执行以下 3 个步骤中的任何一个。
- 从中减去 1。 ( n = n - 1 )
- 如果它可以被 2 整除,则除以 2。(如果 n % 2 == 0 ,则 n = n / 2)
- 如果它可以被 3 整除,则除以 3。(如果 n % 3 == 0 ,则 n = n / 3)
现在的问题是,给定一个正整数 n,求从 n 到 1 的最小步数
例如:
- 对于 n = 1 ,输出:0
- 对于 n = 4 ,输出:2 ( 4 /2 = 2 /2 = 1 )
-
对于 n = 7 ,输出:3 ( 7 -1 = 6 /3 = 2 /2 = 1 )
int 备忘录[n+1]; // 我们将元素初始化为 -1(-1 表示尚未解决)
针对上述问题的自顶向下方法
int getMinSteps ( int n ) {
if ( n == 1 ) return 0;
if( memo[n] != -1 ) return memo[n];
int r = 1 + getMinSteps( n - 1 );
if( n%2 == 0 ) r = min( r , 1 + getMinSteps( n / 2 ) );
if( n%3 == 0 ) r = min( r , 1 + getMinSteps( n / 3 ) );
memo[n] = r ; // save the result. If you forget this step, then its same as plain recursion.
return r;
}
我对 dp 的理解是否正确,或者任何人都可以用更好更简单的方式解释它,以便我可以学习它并可以使用动态编程解决问题。
【问题讨论】: