• [总结-动态规划]经典DP状态设定和转移方程


    马上区域赛,发现DP太弱,赶紧复习补上。

    #普通DP

    CodeForces-546D Soldier and Number Game 筛法+动态规划

    待补

    UVALive-8078 Bracket Sequence

    问以每个字符为左端点的最长括号序列是多长。(包括尖、花、中小括号)
    状态:设dp[i]为从i开始的括号序列最长长度。
    转移:以i+1为起点的最长串后边的字符若与左括号匹配,答案是加上这个字符后边的最长串,否则为零。

    HDU-1024 Max Sum Plus Plus

    给一个序列,找m个不重叠的连续子串,使这几个子串内的元素和的和最大。
    即sum(i1, j1)+sum(i2, j2)+...+sum(im, jm)最大
    状态:dp[i][j]表示选择第i个元素,当前是第j个子串。
    转移:dp[i][j]=max(dp[i-1][j], dp[k][j-1])+num[i], (k<=i-1)
    优化

    1. 维护max(dp[k][j-1])
    2. 滚动数组去掉第一维

    HDU-4055 Number String

    给一个序列相邻元素各个上升下降情况('I'上升'D'下降'?'随便),问有几种满足的排列。
    例:ID
    答:2 (231和132)
    状态:dp[i][j]表示满足以j为结尾的,长度为i的排列方案数。
    转移
    str[i]'I': dp[i][j]=sum(dp[i-1][k]) (1<=k<=j-1)
    str[i]
    'D': dp[i][j]=sum(dp[i-1][k]) (j<=k<=i)
    str[i]=='?': dp[i][j]=sum(dp[i-1][k]) (1<=k<=i)

    HDU-5009 Paint Pearls

    给一串序列,可以任意分割多次序列,每次分割的代价是被分割区间中的数字种数。
    求分割区间的最小代价。n<=5e4
    例:1 3 3
    答:2
    状态:dp[i]表示从0到i序列的分割代价。
    转移:dp[i]=min(dp[j]+cnt[j-1][i]^2)
    优化:双向链表删除元素,优化掉j的选择

    UVA-11584 Partitioning by Palindromes

    给一个字符串序列,问回文串的最少个数。
    例:aaadbccb
    答:3(分为aaa, d, bccb三份)
    状态:dp[i]表示从0到i的回文串最少个数
    转移:dp(i)=min( dp(j-1)+1 | [j, i]是回文串 )
    优化:预处理回文串,复杂度降至O(n^2)

    #区间DP

    HYSBZ-1566 管道取珠

    题意相见 https://www.cnblogs.com/tanglizi/p/9489073.html
    当面对sum a^2的时候,把情形分成两种。当这两种情景(状态)相同时,方案数即为a^2。
    状态和方程待补。

    LightOJ-1422 Halloween Costumes

    想参加聚会,每场聚会需要穿对应的衣服。
    现在有需要参加的聚会的衣服序列。
    对策是可以穿着多件衣服,按聚会不同脱下即可;或者直接在当前衣服上在加一件衣服。
    问最少穿过几件衣服。
    状态:dp[i][j]为第i到第j聚会的穿衣最小数。
    转移:dp[i][j]=min(dp[i][k]+dp[k+1][j-1]), dp[i][j]=dp[i][j-1]+1

    UVA-1331 Minimax Triangulation

    三角剖分系列。
    给一个任意多边形,把它分为多个三角形。
    求某方案中最大的三角形是各方案中最小的面积的三角形面积。
    状态:dp[i][j]为从i到j顺时针区间的多边形最小方案的值。
    转移:dp[i][j]=min(dp[i][j], max(Area(i, k, j), dp[i][k], dp[k][j]))

    HDU-5693 D Game

    待补好题

    UVA-10003 Cutting Sticks

    有根棍子,上面有些分割点(n<50),每次按分割点切割棍子时,费用为当前棍子的长度。
    问有什么样的顺序切完分割点,使总费用最小。
    状态:dp[i][j]表示分割点ij之间棍子的最小切割费用。
    转移:dp[i][j]=min(dp[i][k]+dp[k+1][j])+pos[j]-pos[i]

    ZOJ-3537 Cake

    三角剖分系列。
    给一个多边形,需要分成若干三角形,且每分一次边有代价|xi+xj|*|yi+yj|%p。
    问总代价最小值。
    状态:dp[i][j]表示第i节点到第j节点围城的多边形最小值。
    转移:dp[l][j]=min(dp[l][k]+dp[k][j]+cost(l, k)+cost(k, j));

    三角剖分边界:dp[i][j]=INF, dp[i][i]=dp[i][i+1]=0
    三角剖分原理:dp(i, j)(包含点ij且i<j)表示顺时针从i到j的凸多边形最值,则ijk可表示三角形顶点。

    POJ-1651 Multiplication Puzzle

    矩阵链乘问题
    给一个序列,每次取一个元素的代价是c[i-1]c[i]c[i+1],问取到剩下2个元素的代价最小值。
    状态:设dp(i, j)表示i到j的元素全部选择后的最小值,要注意是全部元素没有被选择过,且端点左右的元素没有被选过
    转移:dp(i, j)=min(dp(i, k-1)+dp(k+1, j)+c[l-1] * c[k] * c[r+1])
    注意

    1. k的取值范围,按定义来就是i~j
    2. 为何状态转移是取k,而其他两数在端点?
      我们可以证明,这样的状态转移包含了所有取数情况,而取(k-1, k, k+1)(先取k元素)是明显不可行的,
      因为接下来区间端点代价计算就是错误的。
    3. 边界条件问题,我们一定要分析区间有0, 1, 2, 3个值的情形。我们发现l>r时,即上次的k选择在了端点上,这部分代价在上一层已经计算完毕。l==r时,按定义发现只能有一种三元组。

    POJ-2955 Brackets

    给一个可能合法的括号序列(包含中小括号),问最长合法子串最长长度。
    貌似可以用简单dp的方法?
    状态:dp[i][j]表示i到j的最长长度。
    转移
    dp[i][i+len]=max(dp[i][i+len], dp[i][k]+dp[k+1][i+len])
    dp[i][i+len]=max(dp[i][i+len], dp[i+1][i+len-1]+2*ismatch(i, i+len))

    以下待补:

    #概率DP

    #树形DP

    #数位DP

    #背包问题

    #典型DP

  • 相关阅读:
    XMLHttpRequest 跨域问题
    jQuery+AJAX实现纯js分页功能
    PHP验证码
    PHP基础
    UIView易忽略点
    UITableView  优化
    SpringBoard界面层级结构分析
    给App在“设置”中添加选项(类似招行App)
    通过USB线SSH登陆到越狱手机上(命令行模式的),不通过wifi
    在IOS项目中使用Lua
  • 原文地址:https://www.cnblogs.com/tanglizi/p/9763280.html
Copyright © 2020-2023  润新知