Dynamic programming ( DP ) is a method used in mathematics , computer science and economics to solve complex problems by decomposing the original problem into relatively simple sub-problems. Dynamic programming is often suitable for problems with overlapping subproblems and optimal substructure properties, and the time consumption of dynamic programming methods is often much less than that of naive solutions.
The basic idea behind dynamic programming is very simple. Roughly speaking, to solve a given problem, we need to solve its different parts (i.e. sub-problems), and then combine the solutions of the sub-problems to arrive at the solution of the original problem. Often many sub-problems are very similar, and for this reason dynamic programming attempts to solve each sub-problem only once, thus reducing the amount of computation: Once the solution to a given sub-problem has been solved, it is memoized so that the same sub-problem is needed next time Check the table directly when solving. This practice is especially useful when the number of repeated subproblems grows exponentially with the size of the input.
Dynamic programming problems satisfy three important properties
Optimal substructure property: If the solution of the subproblems contained in the optimal solution of the problem is also optimal, we say that the problem has the optimal substructure property (that is, it satisfies the optimization principle). The optimal substructure properties provide important clues for dynamic programming algorithms to solve problems.
Sub-problem overlapping property: The sub-problem overlapping property means that when a recursive algorithm is used to solve the problem from top to bottom, the sub-problems generated each time are not always new problems, and some sub-problems will be recalculated many times. The dynamic programming algorithm takes advantage of the overlapping nature of this sub-problem. It only calculates each sub-problem once, and then saves its calculation results in a table. When the calculated sub-problem needs to be calculated again, it is only in the table. Simply look at the results to get high efficiency.
No aftereffect :After the stages are arranged in a certain order, for a given stage state, the state of the previous stages cannot directly affect its future decision-making, but only through the current state. In other words, each state is a complete summary of past history. This is no retrospective, also known as no retrospective.
********************************************************************************************
There are many division methods for dynamic programming classification, and many online are divided according to the state, divided into one-dimensional, two-dimensional, interval, tree and so on. I think it is better to classify the problem according to the type and difficulty of the problem solved by the function. According to my own understanding and induction, the classification of dynamic programming is as follows:
1. Simple basic dp
This type of dp is mainly because some states are easier to represent, the transition equation is easier to think, and the problems are relatively common. It mainly includes recursion , knapsack , LIS (longest increasing sequence) , LCS (longest common subsequence) . For these types, we recommend some good learning materials and topics.
1. Recursion:
The general form of recursion is relatively simple. From front to back, it is enough to classify and enumerate.
Simple:
hdu 2084 number tower is simply recursive from top to bottom
hdu 2018 cow story simple recursive count
hdu 2044 A little bee... Simple recursive counting (Fibonacci)
hdu 2041 Super Staircase Fibonacci
hdu 2050 polyline dividing plane to find recursive formula
recommend:
CF 429B B.Working out four corners recursion
zoj 3747 Attack on Titans count recursive dp with constraints
uva 10328 Coin Toss Same
hdu 4489 The King's Ups and Downs
2. Backpack
Nine lectures on the classic backpack: http://love-oriented.com/pack/
Recommended blog: http://blog.csdn.net/woshi250hua/article/details/7636866
There are mainly 0-1 backpacks , complete backpacks , grouped backpacks , and multiple backpacks .
Simple:
hdu 2955 Robberies 01 Backpack
hdu 1864 maximum reimbursement 01 backpack
hdu 2602 Bone Collector 01 Backpack
hdu 2844 Coins Multipack
hdu 2159 FATE 完全背包
推荐:
woj 1537 A Stone-I 转化成背包
woj 1538 B Stone-II 转化成背包
poj 1170 Shopping Offers 状压+背包
zoj 3769 Diablo III 带限制条件的背包
zoj 3638 Fruit Ninja 背包的转化成组合数学
hdu 3092 Least common multiple 转化成完全背包问题
poj 1015 Jury Compromise 扩大区间+输出路径
poj 1112 Team Them UP 图论+背包
3、LIS
最长递增子序列,朴素的是o(n^2)算法,二分下可以写成o(nlgn):维护一个当前最优的递增序列——找到恰好大于它更新
简单:
推荐:
uva 10635 Prince and Princess LCS转化成LIS
hdu 4352 XHXJ's LIS 数位dp+LIS思想
srm div2 1000 状态压缩+LIS
poj 1239 Increasing Sequence 两次dp
4、LCS
最长公共子序列,通常o(n^2)的算法
uva 111 History Grading 要先排个序
二、区间dp
推荐博客:http://blog.csdn.net/woshi250hua/article/details/7969225
区间dp,一般是枚举区间,把区间分成左右两部分,然后求出左右区间再合并。
poj 1141 Brackets Sequence 括号匹配并输出方案
hdu 4745 Two Rabbits 转化成求回文串
zoj 3541 The Last Puzzle 贪心+区间dp
三、树形dp
比较好的博客:http://blog.csdn.net/woshi250hua/article/details/7644959
一篇论文:http://doc.baidu.com/view/f3b19d0b79563c1ec5da710e.html
树形dp是建立在树这种数据结构上的dp,一般状态比较好想,通过dfs维护从根到叶子或从叶子到根的状态转移。
hdu 4123 Bob's Race 二分+树形dp+单调队列
hdu 4514 求树的直径
hdu 4126 Genghis Kehan the Conqueror MST+树形dp 比较经典
hdu 4756 Install Air Conditioning MST+树形dp 同上
hdu 3660 Alice and Bob's Trip 有点像对抗搜索
CF 337D Book of Evil 树直径的思想 思维
四、数位dp
推荐一篇论文:http://wenku.baidu.com/view/d2414ffe04a1b0717fd5dda8.html
数位dp,主要用来解决统计满足某类特殊关系或有某些特点的区间内的数的个数,它是按位来进行计数统计的,可以保存子状态,速度较快。数位dp做多了后,套路基本上都差不多,关键把要保存的状态给抽象出来,保存下来。
hdu 2089 不要62 简单数位dp
CF 401D Roman and Numbers 状压+数位dp
hdu 4398 X mod f(x) 把模数加进状态里面
hdu 4734 F(x) 简单数位dp
hdu 3693 Math teacher's homework 思维变换的数位dp
hdu 4352 XHXJ's LIS 数位dp+LIS思想
CF 55D Beautiful Numbers 比较巧妙的数位dp
CF 258B Little Elephant and Elections 数位dp+组合数学+逆元
五、概率(期望) dp
推荐博客:http://www.cnblogs.com/kuangbin/archive/2012/10/02/2710606.html
推荐博客:http://blog.csdn.net/woshi250hua/article/details/7912049
推荐论文:
一般来说概率正着推,期望逆着推。有环的一般要用到高斯消元解方程。期望可以分解成多个子期望的加权和,权为子期望发生的概率,即 E(aA+bB+...) = aE(A) + bE(B) +...
ural 1776 Anniversiry Firework 比较基础
hdu 4418 Time travel 比较经典BFS+概率dp+高斯消元
hdu 4586 Play the Dice 推公式比较水
jobdu 1546 迷宫问题 高斯消元+概率dp+BFS预处理
hdu 3853 LOOPS 简单概率dp
hdu 4405 Aeroplane chess 简单概率dp,比较直接
hdu 4089 Activation 比较经典
poj 2096 Collecting Bugs 题目比较难读懂
zoj 3640 Help me Escape 从后往前,比较简单
hdu 4034 Maze 经典好题,借助树的概率dp
hdu 4336 Card Collector 状态压缩+概率dp
hdu 4326 Game 这个题状态有点难抽象
六、状态压缩dp
这类问题有TSP、插头dp等。
推荐论文:http://wenku.baidu.com/view/ce445e4f767f5acfa1c7cd51.html
推荐博客:http://blog.csdn.net/sf____/article/details/15026397
推荐博客:http://www.notonlysuccess.com/index.php/plug_dp/
hdu 4568 Hunter 最短路+TSP
hdu 4539 插头dp
poj 2411 Mandriann's Dream 轮廓线dp
七、数据结构优化的dp
有时尽管状态找好了,转移方程的想好了,但时间复杂度比较大,需要用数据结构进行优化。常见的优化有二进制优化、单调队列优化、斜率优化、四边形不等式优化等。
1、二进制优化
主要是优化背包问题,背包九讲里面有介绍,比较简单,这里只附上几道题目。
2、单调队列优化
推荐论文:http://wenku.baidu.com/view/4d23b4d128ea81c758f578ae.html
推荐博客:http://www.cnblogs.com/neverforget/archive/2011/10/13/ll.html
poj 3245 Sequece Partitioning 二分+单调队列优化
3、斜率优化
推荐论文:用单调性优化动态规划
推荐博客:http://www.cnblogs.com/ronaflx/archive/2011/02/05/1949278.html
4、四边形不等式优化
Recommended blog: http://www.cnblogs.com/ronaflx/archive/2011/03/30/1999764.html
Recommended blog: http://www.cnblogs.com/zxndgv/archive/2011/08/02/2125242.html