• 记录延续性的一类dp


    一些满足最优子结构的关于连续区间的问题,可以尝试在第一维枚举数组的时候,

    添加一个维度表示第i个数是否和前面连续,

    例如dp[i][0]表示i未操作最优,dp[i][1]表示i正在操作最优,dp[i][2]表示i之前已经结束操作最优

    ----------------------------------------------------------------------------------------------------------------

    例题1: Alyona and Strings

    划分k段的最长公共子序列

    增添一维表示i与j是否和i-1,j-1同属一段,0是1否,

    只有当a[i]==b[j],才更新dp[i][j][k][0],由dp[i-1][j-1][k-1][1]和dp[i-1][j-1][k][0]转移而来

    然后dp[i][j][k][1]始终保持大于等于dp[i][j][k][0],这样可以把延续性传递下去

    写的不太好,还是结合代码感觉更能体会是个啥套路

    link

    ----------------------------------------------------------------------------------------------------------------

    例题2:01串,flip一段连续区间让交错子序列最长

    这个就比较套路了,因为最优子结构是满足的

    那么设dp[i][2][3]表示前i个数字,0/1结尾,未反转/反转中/已反转结束的最长长度

    这里反是转结束不包括第i位,方便分清楚,反正最后取最大就从dp[n]那6个里面拿就行了

    这样划分状态之后就能很好的通过状态之间的更新描述出flip的效果了

    上一段代码体会一下更新的套路

    	if(s[i]=='1'){
    			dp[i][1][0]=dp[i-1][0][0]+1;
    			dp[i][0][0]=dp[i-1][0][0];
    			dp[i][1][1]=max(dp[i-1][1][0],dp[i-1][0][1])+1;
    			dp[i][0][1]=dp[i-1][0][1];
    			dp[i][1][2]=max(max(dp[i-1][0][0],dp[i-1][0][2]),dp[i-1][1][1])+1;
    			dp[i][0][2]=dp[i-1][0][2];
    		}

    由于最优子结构,只要保证不会用翻过一次的最优去更新没翻过的最优来维护最优结构就做到约束了

  • 相关阅读:
    Python学习(五)函数 —— 自定义函数
    Python学习(四)数据结构 —— dict
    Python学习(四)数据结构 —— set frozenset
    C++ —— 构建开源的开发环境
    Oracle 数据库 Database Express Edition 11g Release 2 (11.2) 错误解决集锦(使用语法)
    Web —— tomcat 问题解决
    web —— jsp笔记
    Web 前端 —— javaScript
    编程杂谈—— 浮点数
    Web —— java web 项目开发 笔记
  • 原文地址:https://www.cnblogs.com/Drenight/p/8611762.html
Copyright © 2020-2023  润新知