1 / 110

Dynamic Programming

Dynamic Programming. 目录. DP 适用问题第一特征:重叠子问题 Fibonacci Number Binomial Coefficients Shortest paths in DAGs DP 适用问题第二特征:最优子结构 Chain matrix multiplication Longest Increasing Subsequences 运用 DP 解决问题的步骤. 目录. DP 经典问题 Knapsack 背包问题 硬币问题 树状 DP Edit Distance The Partition Problem. 简介.

raanan
Download Presentation

Dynamic Programming

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Dynamic Programming

  2. 目录 • DP适用问题第一特征:重叠子问题 • Fibonacci Number • Binomial Coefficients • Shortest paths in DAGs • DP适用问题第二特征:最优子结构 • Chain matrix multiplication • Longest Increasing Subsequences • 运用DP解决问题的步骤

  3. 目录 • DP经典问题 • Knapsack 背包问题 • 硬币问题 • 树状DP • Edit Distance • The Partition Problem

  4. 简介 • 动态规划(Dynamic Programming, DP)是在20世纪50年代由一位卓越的美国数学家Richcard Bellman发明的。它作为一种重要的工具在应用数学中被广泛的应用。它不仅可以解决特定类型的优化问题,还可以作为一种通用的算法设计技术为计算机服务。

  5. DP适用问题的第一特征 • 所求解的问题具有重叠子问题。 • 解决方法 • 进行记忆化求解。(用空间换时间) • 依照某种合适次序计算,以避免重复计算。

  6. Fibonacci Number • 求Fibonacci数: f(n) = f(n-1) + f(n-2) n>1 f(0)=0, f(1)=1

  7. Fibonacci Number • 常规递归 long long fib_r(int n) { if (n == 0) return 0; if (n == 1) return 1; return (fib_r(n-1) + fib_r(n-2)); } • 指数级时间复杂度,无法忍受。

  8. Fibonacci Number • 常规递归 • 重叠子问题,导致重复计算。

  9. Fibonacci Number • 自顶而下,记忆化求解 long longfib_c(int n) { if (f[n] == -1) f[n] = fib_c(n-1) + fib_c(n-2); return (f[n]); } long longfib_c_driver(int n) { f[0] = 0; f[1] = 1; for (inti=2; i<=n; i++) f[i] = -1; return (fib_c(n)); }

  10. Fibonacci Number • 自底而上,顺序求解 long longfib_dp(int n) { long long f[MAXN + 1]; f[0] = 0; f[1] = 1; for (inti=2; i<=n; i++) f[i] = f[i-1] + f[i-2]; return (f[n]); }

  11. Fibonacci Number • 自底而上,顺序求解。空间优化 long longfib_ultimate(int n) { /* back2,back1 are last two values of f[n] */ long long back2 = 0, back1 = 1; long long next; if (n==0) return 0; for (inti=2; i<n; i++) { next = back1 + back2; back2 = back1; back1 = next; } return (back1+back2); }

  12. Binomial Coefficients • C(n,k)表示从n个不同物体中选出k个的组合数 • C(n,k)=n!/((n−k)!k!)=C(n-1,k-1)+C(n-1,k) Pascal’s triangle Matrix representation

  13. Binomial Coefficients Const int MAXN = 100; long long binomial_coefficient(int n, int k) { long long bc[MAXN+1][MAXN+1]; for (int i = 0; i<=n; i++) bc[i][0] = 1; for (int j = 0; j<=n; j++) bc[j][j] = 1; for (int i = 1; i<=n; i++) for (int j=1; j<i; j++) bc[i][j] = bc[i-1][j-1] + bc[i-1][j]; return ( bc[n][k] ); }

  14. Shortest paths in DAGs 以S为源点对左图中的所有结点进行拓扑排序,得到右图。则计算从源点S到点D的最短路径可以表示为: dist(D) = min{dist(B)+edge(BD), dist(C)+edge(CD)} = min{dist(B)+1, dist(C)+3} 这里的B和C是结点D的两个前驱结点。

  15. Shortest paths in DAGs Topologically sort vertices in G; Initialize all dist(.) values to INF dist(s) = 0 for each v ∈ V , in linearized order do dist(v) = min(u,v) ∈E { dist(u) + w(u,v) }

  16. Example 求s到任意点的最短距离 6 1 u r t s v w 2 7 –2 5 –1  0     4 3 2

  17. Example 6 1 u r t s v w 2 7 –2 5 –1  0     4 3 2 dist[r] = , dist[s] = 0

  18. Example 6 1 u r t s v w 2 7 –2 5 –1  0 2 6   4 3 2

  19. Example 6 1 u r t s v w 2 7 –2 5 –1  0 2 6 6 4 4 3 2 dist[t]=min{dist[s]+2, dist[r]+3}

  20. Example 6 1 u r t s v w 2 7 –2 5 –1  0 2 6 5 4 4 3 2 dist[u]=min{dist[s]+6, dist[t]+7}

  21. Example 6 1 u r t s v w 2 7 –2 5 –1  0 2 6 5 3 4 3 2 dist[v]=min{dist[t]+4, dist[u]-1}

  22. Example 6 1 u r t s v w 2 7 –2 5 –1  0 2 6 5 3 4 3 2 dist[w]=min{dist[t]+2, dist[u]+1, dist[v]-2}

  23. 动态规划术语 • 状态:贴切,简洁的描述出事物性质的单元量。例如:Dist[x]。 要求:状态与状态之间可以转移,以便有初始状态逐渐转移到目标状态,找到问题的解。 • 阶段:若干性质相近可以同时处理的状态的集合。就是计算状态的顺序。 要求:每个阶段中状态的取值只与这个阶段之前的阶段中的状态有关,与这个阶段之后的阶段中的状态无关。

  24. 动态规划术语 • 状态转移方程:前一个阶段中的状态转移到后一个阶段的状态得演变规律,即相邻两个阶段的状态变化方程。 Dk(i) = opt { Dk-1(j) + cost(i,j) } 第k阶段的i状态与第k-1阶段的j状态有关 • 决策:计算每个状态时作出的选择。

  25. 动态规划时间效率 动态规划解决问题的方法是通过解决很多小的问题而解决大问题。 动态规划的效率取决于两个因素:子问题的数量和子问题的解决效率。 时间效率:子问题的数量*子问题的时间效率。

  26. DP适用问题的第二特征 • 所求解的问题具有最优子结构,即问题的一个最优解中包含子问题的最优解。 • 例如,矩阵链乘法问题中,Ai×Ai+1×…×Aj的一个最优加全部括号把乘积在和之间分裂,它包含了两个子问题Ai×Ai+1×…×Ak和Ak+1×Ak+2×…×Ak的最优解。

  27. Chain matrix multiplication

  28. Chain matrix multiplication

  29. Chain matrix multiplication For 1≤ i≤k≤j ≤n, define C(i,j) = minimum cost of multiplying Ai×Ai+1×…×Aj for i = 1 to n: C(i, i) = 0 for s = 1 to n - 1: for i = 1 to n - s: j = i + s C(i, j) = min{C(i, k) + C(k + 1, j) +mi-1·mk·mj : i≤k ≤j} return C(1, n) The subproblems constitute a two-dimensional table, each of whose entries takes O(n) time to compute. The overall running time is thus O(n3).

  30. Chain matrix multiplication • 矩阵链相乘问题具有最优子结构,即问题的一个最优解中包含子问题的最优解。 • Ai×Ai+1×…×Aj的一个最优加全部括号把乘积在和之间分裂,它包含了两个子问题Ai×Ai+1×…×Ak和Ak+1×Ak+2×…×Ak的最优解。

  31. 相关习题 sicily1345 能量项链 • 给出一串项链,每次可以选相邻两个珠子进行聚合,释放出一定的能量,并产生一个新珠子。项链是头尾相接的。求释放的能量的总和的最大值。 • 项链长度不超过100。

  32. Longest Increasing Subsequences

  33. Longest increasing subsequence • Algorithm:

  34. Longest Increasing Subsequences L(0) = 1, P(.) = -1 For i = 1, 2, …, n L(i) = 1 + max0<j<i{L(j)}, where Sj<Si P(i) = j L(i) is the length of the longest path ending at i (plus 1). Time complexity is O(n2), the maximum being when the input array is sorted in increasing order.

  35. Longest Increasing Subsequences

  36. 相关习题 • 推荐题目: sicily1060 Bridging Signals (需要用特殊法做) sicily1685 Missile(最长不单调子序列,数据小,O(n2)) sicily1448 Antimonotonicity(最长不单调子序列,数据大,O(n))

  37. 小结 • 动态规划的一般步骤 • 考察问题结构,给出状态表示方式,列出递归方程(状态转移方程) • 分析复杂度,若复杂度较高则需要优化。 • 用递推或记忆化搜索实现。 • 根据计算最优值过程中的信息,递归的构造一个最优解。 • 应用动态规划的前提条件 • 重复子问题 • 最优子结构

  38. 经典问题

  39. 背包问题 • 01背包问题 • 完全背包问题 • 多重背包问题 • 分组的背包问题 • 有依赖的背包问题

  40. 01背包问题 • 有N件物品和一个容量为V的背包。第i件物品的费用是c[i],价值是w[i]。求解将哪些物品装入背包可使价值总和最大。 • 这是最基础的背包问题,特点是:每种物品仅有一件,可以选择放或不放。 • 状态:用f[i][v]表示前i件物品恰放入一个容量为v的背包可以获得的最大价值,其状态转移方程为f[i][v]=max{ f[i-1][v], f[i-1][v-c[i]]+w[i] }。 • 复杂度分析: • 状态数:O(NV), 迁移:O(1) • 总复杂度:O(NV)

  41. 状态f[i][v]表示前i件物品恰放入一个容量为v的背包可以获得的最大价值。状态f[i][v]表示前i件物品恰放入一个容量为v的背包可以获得的最大价值。 • 对于“将前i件物品放入容量为v的背包中”这个子问题,若只考虑第i件物品的策略(放或不放),那么就可以转化为一个只牵扯前i-1件物品的问题。 • 如果不放第i件物品,那么问题就转化为“前i-1件物品放入容量为v的背包中”,价值为f[i-1][v]; • 如果放第i件物品,那么问题就转化为“前i-1件物品放入剩下的容量为v-c[i]的背包中”,此时能获得的最大价值就是f[i-1][v-c[i]]再加上通过放入第i件物品获得的价值w[i]。 • 状态转移方程: f[i][v]=max{ f[i-1][v], f[i-1][v-c[i]]+w[i] }

  42. 时间复杂度O(NV) • 由于计算f[i][v]时只用到f[i-1][v]和f[i-1][v-c[i]],在每次主循环中我们以v=V..0的顺序推f[v],这样就保证推f[v]时f[v-c[i]]保存的是状态f[i-1][v-c[i]]的值,f[v]保存的是状态f[i-1][v]的值。 • 伪代码如下: for i=1..N for v=V..0 f[v]=max{f[v], f[v-c[i]] + w[i]}; • 空间复杂度成功降到O(V)

  43. 抽象成过程ZeroOnePack,表示处理一件01背包中的物品,两个参数cost、weight分别表明这件物品的费用和价值。抽象成过程ZeroOnePack,表示处理一件01背包中的物品,两个参数cost、weight分别表明这件物品的费用和价值。 void ZeroOnePack(cost,weight){ for v=V..cost f[v]=max{f[v],f[v-cost]+weight} } • 01背包问题的伪代码就可以这样写: for i=1..N ZeroOnePack(c[i],w[i]);

  44. 初始化问题 • 如果题目要求“恰好装满背包”时的最优解 在初始化时除了f[0]为0其它f[1..V]均设为-∞ • 如果并没有要求必须把背包装满,初始化时应该将f[0..V]全部设为0 • 初始化的f数组事实上就是在没有任何物品可以放入背包时的合法状态。如果要求背包恰好装满,那么此时只有容量为0的背包可能被价值为0的nothing“恰好装满”,其它容量的背包均没有合法的解,属于未定义的状态,它们的值就都应该是-∞了。如果背包并非必须被装满,那么任何容量的背包都有一个合法解“什么都不装”,这个解的价值为0,所以初始时状态的值也就全部为0了。

  45. 推荐题目: sicily1782 Knapsack sicily1146 采药 sicily1342 开心的金明

  46. 完全背包问题 • 有N种物品和一个容量为V的背包,每种物品都有无限件可用。第i种物品的费用是c[i],价值是w[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。 • 状态f[i][v]表示前i件物品恰放入一个容量为v的背包可以获得的最大价值,其状态转移方程为 f[i][v]=max{ f[i-1][v], f[i][v-c[i]]+w[i] } • 时间复杂度O(NV)

  47. 完全背包问题 • O(VN)的算法 空间优化,伪代码: for i=1..N for v=0..V f[v]=max{f[v],f[v-c[i]]+w[i]} void CompletePack(intcost,int weight) { for(int v=cost;v<=V;++v) f[v] >?= f[v-cost]+weight; }

  48. 01背包按照v=V..0的逆序来循环,要保证第i次循环中的状态f[i][v]是由状态f[i-1][v-c[i]]递推而来。换句话说,这正是为了保证每件物品只选一次,保证在考虑“选入第i件物品”这件策略时,依据的是一个绝无已经选入第i件物品的子结果f[i-1][v-c[i]]。01背包按照v=V..0的逆序来循环,要保证第i次循环中的状态f[i][v]是由状态f[i-1][v-c[i]]递推而来。换句话说,这正是为了保证每件物品只选一次,保证在考虑“选入第i件物品”这件策略时,依据的是一个绝无已经选入第i件物品的子结果f[i-1][v-c[i]]。 • 完全背包的特点恰是每种物品可选无限件,所以在考虑“加选一件第i种物品”这种策略时,却正需要一个可能已选入第i种物品的子结果f[i][v-c[i]],所以就可以并且必须采用v=0..V的顺序循环。即f[i][v]=max{f[i-1][v],f[i][v-c[i]]+w[i]}

  49. 二维背包 • 对于每件物品,具有两种不同的费用;选择这件物品必须同时付出这两种代价;对于每种代价都有一个可付出的最大值(背包容量). 问怎样选择物品可以得到最大的价值. 设第i件物品所需的两种代价分别为a[i]和b[i]. 两种代价可付出的最大值(两种背包容量)分别为V和U. 物品的价值w[i]. • 分析:费用加了一维,只需状态也加一维即可. 设f[i][v][u]表示前i件物品付出两种代价分别为v和u时可获得的最大价值。状态转移方程就是: f[i][v][u]=max{ f[i-1][v][u],f[i-1][v-a[i]][u-b[i]]+w[i] }

  50. 二维背包 • 二维背包很容易扩展到多维背包 • “二维费用”的条件有时是以这样一种隐含的方式给出的:最多只能取M件物品. 这事实上相当于每件物品多了一种“件数”的费用,每个物品的件数费用均为1,可以付出的最大件数费用为M.

More Related