2014专题训练之动态规划总结

一、斜率优化:

        若一个DP方程可以表示为f[i] = min(f[j] + cost(i, j)),假设j是最优选择,那么对于任意的k,都有f[j] + cost(i, j) >= f[k] + cost(i, j)。

        若将上式移项得到左边可以表示为(g[j] - g[k]) / (h[j] - h[k]) ,右边是一个与j和k无关的式子,则可以用队列来优化DP。

        队列维护的是一个下凸的图形,下凸就是斜率逐渐变大,证明略。

        A - MAX Average Problem

        B - Lawrence


二、四边不等式优化:

        若一个DP方程可以表示为f[i][j] = min(f[i][k] + f[k + 1][j] + cost(i, j)),且对于cost(i, j)若固定j,cost(i, j + 1) - cost(i, j) 是一个关于i递减的函数,则s[i][j - 1] <= k <= s[i + 1][j]。

        C - Tree Construction


三、序列上的DP:

        D - Number String

        序列上的DP很多是等价替换的思想。

        对于这题,dp[i][j]表示第i个位置填j(1 <= j <= n)且满足要求的序列有多少个。但是这样表示是有后效性的。

        换一种表示方法:dp[i][j]表示第i个位置填j(1 <= j <= i)且满足要求的序列有多少个。考虑dp[i - 1][k],若把这序列上大于等于j的的数字全部加1,这个序列仍然是合法的,但是j却消失了,i却用掉了(因为原来序列有i-1)。


        E - Reverse the prefix

        f[i][j]表示前i个字母采取最多j次翻转得到的最小序列。g[i][j]表示前i个字母采取最多j次翻转得到最大的序列。

        转移比较简单。


四、单调队列优化

        可以用单调队列优化的DP一般是用于限定长度的区间,且区间有整体移动的趋势。即每一个元素是逐次进出区间,且只有一次。队列里的值是单调的,一般dp[i]会直接等于Q.front() + cost;

        F - Cut the Sequence

        显然,dp[i] = dp[j] + max(a[j + 1], a[i]),其中且sum(j + 1, i) <= m。

        但是此题dp[i]不一定等于Q.front() + cost,因为cost是动态的且不与队列的单调性一样。

        一个最优的选择j,a[j]必定大于后面所有数(自己想)。


五、数位DP

        G - Balanced Number

        反正我用数位DP做挂了,网上的都是暴力深搜的。


六、概率DP

        我概率DP渣渣啊,主要是状态的表示方法太灵活了。递推方式有从结果出发和从始态出发两种。而且往往会出现DP[i]用到DP[j],DP[j]用到DP[i]这样的情况,常用解决的方法有迭代求解和高斯消元。

H - Activation

        I - Maze

        这两题都是用的迭代法,H题略。

I题对于当前的点,dp[i] = A * dp[1] + B * (dp[father] + sigma(dp[son])) + C → dp[i] = A * dp[1] + B * dp[father] + B * sigma(dp[son]) + C → dp[i] = A * dp[1]  + B * dp[father] + D

对于每一个节点,用一个三元组(A,B,D)来表示,然后不知道怎么说,就是从儿子的ABD更行自己的ABD,看代码吧。


七、斯坦纳树

        最小生成树是斯坦纳问题的一种特殊情况。给N个点和相应的边,选定K个点,问如何选择边使得这K个点联通并且边权和最小。

        dp[i][s]表示以i为根,使得k个点的联通情况为s的最小边权和。dp[i][s] = min(dp[i][p | st[i]] + dp[i][(s - p) | st[i]]); 然后spfa()

        J - Peach Blossom Spring  



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值