赞
踩
动态规划(Dynamic Programming)是求解决策过程最优化的数学方法。把多阶段过程转化为一系列单阶段问题,利用各阶段之间的关系,逐个求解,创立了解决这类过程优化问题的新方法——动态规划。
如果要求一个问题的最优解(通常是最大值或者最小值),而且该问题能够分解成若干个子问题,并且小问题之间也存在重叠的子问题,则考虑采用动态规划。
能采用动态规划求解的问题的一般要具有3个性质:
有一头母牛,它每年年初生一头小母牛。每头小母牛从第二个年头开始,每年年初也生一头小母牛。请问在第n年的时候,共有多少头母牛?
f i b ( n ) = f i b ( n − 1 ) + f i b ( n − 2 ) fib(n) = fib(n - 1) + fib(n - 2) fib(n)=fib(n−1)+fib(n−2)
0 0 0 1 1 1 1 1 1 2 2 2 3 3 3 5 5 5 8 8 8 13 13 13 21 21 21 34 34 34
int fib(n){
return (n < 2) ? n : fib(n - 1) + fib(n - 2);
}
int fib(n){
if(n < 2) return n;
return fib(n - 1) + fib(n - 2);
}
T ( n ) = T ( n − 1 ) + T ( n − 2 ) + 1 > 2 ⋅ T ( n − 2 ) + 1 = O ( ( 2 ) n ) T(n) = T(n - 1) + T(n - 2) + 1 \gt 2 \cdot T(n - 2) + 1 = O((\sqrt{2})^n) T(n)=T(n−1)+T(n−2)+1>2⋅T(n−2)+1=O((2 )n)
T ( n ) = T ( n − 1 ) + T ( n − 2 ) + 1 = O ( f i b ( n ) ) = O ( Φ n ) T(n) = T(n - 1) + T(n - 2) + 1 = O(fib(n)) = O(\varPhi ^ n) T(n)=T(n−1)+T(n−2)+1=O(fib(n))=O(Φn)
Φ = 1 + 5 2 = 1.618... \varPhi = \frac{1 + \sqrt{5}}{2} = 1.618... Φ=21+5 =1.618...
Φ 36 ≈ 2 25 \varPhi^{36} \approx 2^{25} Φ36≈225
Φ 5 ≈ 10 \varPhi^{5} \approx 10 Φ5≈10
刚刚递归算法的不足之处在于重复计算了大量相同的子问题,浪费了大量时间
好记性不如烂笔头
记忆化搜索 M e m o i z a t i o n Memoization Memoization
备忘录 L o o k − u p Look-up Look−up T a b l e Table Table → \to → A r r a y Array Array
用一个数组记录需要重复计算的子问题
这就是动态规划的第一种实现方式,也是最容易理解的写法:记忆化搜索
const int maxn = 1e6 + 5; int f[maxn]; void init(){ memset(f, -1, sizeof(f)); f[0] = 0; f[1] = 1; } int fib(n){ int& ret = f[n] if(ret != -1) return ret; ret = fib(n - 1) + fib(n - 2); return ret; }
a 98765 = ? ? ? a^{98765} = ??? a98765=???
a 9 ⋅ 1 0 4 + 8 ⋅ 1 0
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。