【动态规划】动态规划总结

数组表示一个集合,表示的值是集合的一个特性(可以自己定),每一个集合都有几个限制条件,求出的值必须满足这个特性。转移方程的推导可以看做是把一个集合划分成几个不同的子集,这些子集的特性是已知的,就可以转移。

1.状态表示:集合、属性

2.状态转移:划分集合

重要思想:

每个子问题的决策不能被后面其他未解决的问题影响
某阶段的状态一旦确定,则此后过程的演变不再受此前各种状态及决策的影响
某阶段的状态一旦确定,未来的决策不会再影响前面的 
未来的决策不会受到前面的影响(只能直接调用结果) ,也不会影响前面的决策 

注意问题:

1.每一个存在和合理的状态的值都必须存在,且值必须是正确的。如果有一个状态不合理,必须和所求的属性赋值一个极大的相反值

2.如果发现当前维数的状态方程难以推导,可以考虑再开一维

3.分组背包的理解:分组背包就是把01背包的for循环顺序交换了一下,理解:交换之后,先枚举组数,然后枚举体积,在体积里面枚举每一组的物品,所以,在更新一个体积的时候,就只会用这一个组内,能使当前结果最优的一个进行更新,就可以实现,一组只取一个的目的。

4.如果从一个集合要推出当前这个集合的话,就必须明确他们之间元素的关系,如果不能确定,南无状态转移方程几有可能推错了,需要重新从一个确定的状态转移。集合之间

5.有的背包里面,时间可以使价值也同时可以使体积

6.顺推和倒推的最优子结构满足性区别,(顺推)它以前各阶段的状态无法直接影响它未来的决

策,所以,如果有延后性的满足条件,我们就可以倒推来解决这个问题

6.最长上升子序列可以开一个数组记录一下过程,记录一下过程中的分数之和

7.有多种情况组合而成的时候,可以把这些情况拆解开,分成多个分别dp,再找出他们之间的关系

8.矩阵求的dp有很多,一般都是拆解开,分多个dp

9.依赖背包(树形)就是分组背包的变形,是枚举分给每一个子树多少体积,这相当于分组背包里,一个组里的一个物品,一个物品当然不能被选两遍,所以,一个子树的一种体积状态也不能被更新两次。但是,这个子树的每一种体积的状态枚举和顺序是无关的。由此我们可以得出,外层枚举体积的循环要倒序,但是内层枚举每一个子树的体积的时候,不用在乎顺序的问题(和分组背包一样),都是要求当前体积下,一种子树体积去更新局部最优解。

10.注意,不成立的状态,不可能的状态,如果存在后面会转移的可能性,就要把它的值设为与答案完全相反的一个值,防止用这个值更新出一种不成立的最值答案。

11.dp的时候,该开long long就开long long不要吝啬,否则就会爆0,但是有的时候,看题上的空间限制,如果开得太多,也会爆0,

12.dp的转移方程其实不难,基本都可以自己推出来。

13.有的题目上的物品并不是真正的物品,可能转化为(一艘船),用看似不想关联的事物做每一个单独的物品

14.注意考虑最差情况的转移,并非只有最好的情况可以转移(可能最好的情况不合法)

15.注意差值bool的动态规划,表示一种状态可不可行

16.动态规划还可以使用倍增的思路,比较简单一些,就和lca一样,把一种状态的2^0的状态预处理一下,然后就可以使用倍增快速处理出数据,

17.如果有两个元素之间的关系,可以开两个数组,分别作第一关键字和第二关键字,这样dp就有了转移的可能

18.区间dp就是先枚举区间长度,枚举左端点,再枚举断点,注意断点的定义,正不能把一个l,r枚举两次 。如果k是包括k算在左侧区间的话,结尾就是<r,反之,就是从l+1开始枚举。假设两边都包含,那样就会把l,r算两次,而且,值还会被加两次

19.区间dp在赋初值的时候,看清楚初值和代价的区别,若把代价赋成初始值,就会算两遍len==1的初始值,

20.排列问题可以考虑插入后的状态变化(一般是有序插入)

21.对dp无后效性的理解:就是在dp的时候必须要满足最优子结构,满足之后,在下一次决策时可以调用当前的最大值进行转移,可以知道,这种一定是最大的情况。无后效性就是指,如果当前决策的最优性会受到以后决策的影响,那么,就不可能进行状态转移,所以设计一个结构,使决策的性质只会在两次之间传递,只会和前一个有影响,或者是能推出来下一个,那么,转移就是有可能的

21.动态规划中的压缩路径问题,压缩路径优化数组, t * ( t - 1)就是路径,可以看做不论怎样走,都可以先走一段,然后具体走

22.动态规划主要还是看清题目上给的限制条件,用限制条件卡循环范围和转移方程

23.有返回值的函数如果不写retrun就会奇妙!!!!

24.(dp自己一个小时推出来的感觉简直不要太爽)

25.数组赋初始值极大值或者极小值的时候,尽量在for内部赋值,这样就会防止一些本应该是0的状态被memset改变

26.dp输出方案可以使用贪心的思想,只要是可行解就行

27.在进行背包的时候,有时会发现背包的体积太大,物品的体积也很大,我们就可以把每一件物品减去 mi - 1 ( mi 是物品中的最小体积),把总体积设为sv(物品的总体积 - n*mi),然后开二维的背包,三重for循环,只要判断一下j + k*mi<= w就可以

28.可以用pair来保存下标,然后记录转移就可以很方便

29.字符串区间染色的问题可以用区间dp来做

30.其实有的题目中判断情况成不成立可以转化为非常简单的问题,比如区间满覆盖

31.dp的有些问题也可以使用贪心的思想

32.dp方程的初始化最好是赋为极值,因为你不知道哪个不合法的状态会转移东西,比如f[0][5]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值