算法设计与分析—动态规划

动态规划

首先将计算机问题分解为规模较小的子问题,然后自底向上地求解各个子问题,并将子问题的解存储在一个数据结构中。

  • 优化子结构
  • 重叠子问题

问题实例

(1)0-1背包问题

  • 一个容量为C的背包和n个物品,其中第i个物品体积为weight[i],其价值为value[i],输出一个物品装包方案使得每个物品要么放入背包要么不放入背包,背包的内物品总重量不超过C且总价值达到最大值
  • 用一个数组f[i][j]表示,在总共有i个物品,容量为j的情况下背包问题的最优解。第i个物品可以选择放进背包或者不放进背包(这也就是0和1)。
  • 如果放进背包(前提是放得下):
f[i][j]=f[i-1][j-weight[i]+value[i];
  • 如果不放进背包:
f[i][j]=f[i-1][j];
  • 状态转移方程
f[i][j]=max(f[i-1][j],f[i-1][j-weight[i]+value[i]); 

(2)完全背包问题(一)

  • 一个容量为C的背包和n个物品,第i个物品体积为weight[i],其价值为value[i],每个物品都有无限多件,现在往背包里面装东西,怎么装能使背包的内物品价值最大
  • 用一个数组f[i][j]表示,在总共有i个物品,j为背包可以容纳的重量,有i种物品时,对于第i种物品,要么取或者不取,至于取多少个我们并不关心。
  • 状态转移方程
f[i][j]=max(f[i-1][j], f[i][j-weight[i]]+value[i], i=0,...,N);

(3)完全背包问题(二)

  • 用一个数组f[i][j]表示,在总共有i个物品,j为背包可以容纳的重量,有N种物品,对于每种物品假设至少包含一个,至于到底包含多少个我们并不关心。
  • 状态转移方程
f[j]=max{f[j-weight[i]]+value[i], i=0,...,N}  

(4)最少硬币找零问题(一)

  • 给予不同面值的硬币若干种,如1 5 10 20 50 100,并且每种硬币个数无限多,如何用若干种硬币组合为某种面额的钱,使硬币的的个数最少?
  • 假设j为需要找零多少元,有i种硬币,找零时对于第i种硬币,我们只考虑取或者不取,至于取多少个我们并不关心。
  • 状态转移方程
f[i][j]=min(f[i-1][j],f[i][j-coins[i]]+1);  

(5)最少硬币找零问题(二)

  • 假设j为需要找零多少元,有N种硬币,对于每种硬币,我们可以依次假设f(i)中至少包含一个coins[j] (j=0, 1……N) ,然后得到所需的最少硬币是f(j- coin[i])+1,最后再从这N次假设中选出最小的就是f(i)。
  • 状态转移方程
f[j]= min{f[j-coins[i]]+1, i=0,...,N};

(6)Word Break问题

要求一个非空字符串s,一个非空的字符串词典,判断s能够通过空格组成一个序列是词典里的多个单词
例如:s= ” leetcode”,dict=[“leet”,”code”],因为“leetcode”可以改成“leet code”故返回1。

  • 状态转移方程
dp[i+Len]=dp[i]&&dict.find(s.substr(i,Len)); #Len:[minlen,maxlen],i:[0,s.size()]  

你可能感兴趣的:(算法设计与分析,动态规划)