动态规划是一种非常精妙的算法思想,它没有固定的写法,极其灵活,常常需要具体问题具体分析
什么是动态规划
动态规划(Dynamic Programming,DP)是一种用来解决一类最优化问题的算法思想。简单来说,动态规划将一个复杂的问题分解成若干个子问题,通过综合子问题的最优解来得到原问题的最优解,需要注意的是,动态规划会将每个求解过的子问题的解记录下来,这样,当下一次又碰到同样的子问题时,就可以直接使用之前记录的结果,而不是重复计算。
一般可以使用递归或递推的写法来实现动态规划,其中递归写法在此处又称作记忆化搜索
动态规划的递归写法
以斐波那契(Fibonacci)数列为例,斐波那契数列的定义为F0=1,F1=1,Fn=Fn-1+Fn-2(n>=2)
int F(int n){
if(n==0||n==1) return 1;
else return F(n-1)+F(n-2);
}
事实上,这个递归会有很多重复的计算,由于没有保存中间计算的结果,实际复杂度会高达O(2^n),即每次都会计算F(n-1)和F(n-2)这两个分支,基本不能承受n较大的情况。
为了避免重复计算,可以开一个一维数组dp,用以保存已经计算过的结果,其中dp[n]记录F(n)的结果,用dp[n]==-1表示F(n)当前还没有被计算过
int dp[MAXN];
然后就可以在递归当中判断dp[n]是否是-1;如果不是-1,说明已经计算过F(n),直接返回dp[n]就是结果,否则,按照递归式进行递归,代码如下:
int F(int n){
if(n==0||