浅谈动态规划

浅谈动态规划


前言

​ 本蒟蒻认为,在算法竞赛中,最重要的两个算法就是动态规划和搜索。后者可以暴力骗分,也可通过剪枝或记忆化、迭代加深等优化来解决问题。而前者则可以在非指数级时间复杂度内解决许多抽象而复杂的问题。


定义

​ 动态规划($$DP,Dynamic Programming$$)是求解决策问题最优解的算法。

​ 一般来说,动态规划可被拆分成三个部分:状态决策阶段。也有三个基本条件:子问题重叠性无后效性最优子结构性质

1.状态、决策、阶段:

​ 为了降低求解的时间复杂度,动态规划算法把原问题视作若干个重叠子问题的逐层递进,每个子问题都有一个状态,构成整个问题的一个阶段,并通过不同的决策方案向更深层问题转移。

2.子问题重叠性、无后效性、最优子结构性质

​ 动态规划将问题分成了若干个子问题,而这些子问题的解决方案被储存在一个表中,而不是需要时再重复计算(类似于记忆化搜索)。而当一个问题,没有共同的子问题,也就是说,其所有的子问题都需要重新计算(无子问题重叠性),那么动态规划是没有用的。

​ 在动态规划中,一个子问题通过决策转移至后续问题,而这个子问题不能被后续问题所影响,这就是无后效性。也就是说,如果将动态规划的状态转移成一张图,那么这张图应该是一张有向无环图,而转移顺序应该是这张图的拓扑序

​ 对于一个问题,它可以由多个子问题到达,也就是说,下一阶段的最优解应该能够由前面各阶段子问题的最优解导出,这个条件被称作最优子结构。对于一个问题,其的最优解是由前阶段最优子状态,再与最优转移决策综合而来。


类别与优化

​ 对于动态规划,本蒟蒻把其分为了这几个类别

​ 1.线性DP

​ 2.区间DP

​ 3.树形DP

​ 4.状压DP

​ 5.计数DP

​ 6.数位DP

​ 而DP的转移有时需要时空上的优化,如:

​ 1.优化状态

​ 2.数据结构优化

​ 3.单调栈、队列优化

​ 4.斜率优化

​ 5.四边形不等式

​ 6.优化枚举顺序

​ 7.倍增优化


一般步骤

​ 1.确定一个无后效性、可高效转移的状态

​ 2.确定枚举顺序以及初始值

​ 3.确定转移方式

​ 4.确定答案由哪些状态得来

​ 例:0/1背包问题

​ 1.设F[i]为包内体积为i时能获得的最大状态

​ 2.先遍历每个物品,又由于每个物品只能选一次,所以枚举体积需要倒序枚举

​ 3.F[j]这个状态可以由该物品不选到达,也可以由选择该物品到达,也就是F[j] = max(F[j],F[j-v[i]]+w[i]);

​ 4.答案是所有状态的最大值


总结:

​ 动态规划一直是算法竞赛中的重点。著名的算法学家、JDOI滴神——QYB曾说过:''想不出来就想动态规划''

​ 动态规划的应用十分广泛,但也需要极强的抽象思想,才能设定出高效的状态与转移方程

​ 最后,分享一下我特别喜欢的一句话:

你的一个又一个阶段是由上天安排的,而你,决定的是在这一阶段可以由上一阶段的哪些状态转移而来。越勤奋,越幸运,并不代表这一次你决策的方向有多么优秀,却代表着现在的这一个状态能够续写多少可能的结果
——《动态规划》

原文地址:https://www.cnblogs.com/Marcelo/p/13972454.html