动态规划实际上就是把一些要重复计算的值先存入dp[][]数组里,以免重复计算。比如一串数字第n个数等于前两个数相加,很简单,我们用递归思想可以很容易求出第n个数。但是在这个递归方法里其实计算了很多重复的数,如果n特别大,那么就要递归很多次使得算法变慢。但是如果我们写入一个数组,将算过的值先存入数组以免重复计算,这样,递归的次数就会变少,速递就会变快。
在这里,我们写入了一个数组arr[],在加上一个判断,判断是否重复计算过,最后在返回arr[n],就能更快的得到第n个数。
动态规划最经典的就是背包问题,思想很简单就是将每个重量的最优解存入数组,而动态规划最重点的就是状态转移方程。假如有5件物品,他们的重量和价值分别是 (7kg,$6) (2kg,$3),(1kg,$6),(4kg,$10),(1kg,$2),背包可以装7kg。求可以装价值最高是多少。
在这里我们要求背包装的价值最高,我们要先计算1-7kg每种重量价值最高。这里用动态规划思想,先建立一个dp[][]二维数组,纵坐标为1-5种物品,横坐标为1-7kg的重量。
首先初始化,将第一个物品存入数组,第一个物品重量为7kg,价值为6,此时7kg最高的价值为6.
接着我们存入后四件物品时,就依照我们初始化的数据,如果在7kg时下一件或多件物品的价值大于之前存入的价值,则存入更大的价值即最优解。比如第三件物品存入时,在dp[3][3]的地方,意思为3kg,而第三件物品 重量只有2kg,还剩余1kg的空间,那我们就加上1kg的最优解看是否大于dp[2][3]的值,可以得到3+6>3,则在dp[3][3]存入3+6.由此我们可以写出一个状态转移方程
dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);
最后返回7kg最下面的值,就能得到背包可以装的最大价值。
总结 :1,动态规划首先要思考哪些值可以避免重复计算
2,把重复计算的最优解存入数组里,后面依照前面存入的最优解再计算
3,重点在于如何写出状态转移方程