刘书学习笔记(4)线性结构上的dp(上)

LIS

dp[i]=max{dp[j]}+1

LCS

A[i]=A[j] dp[i][j]=dp[i-1][j-1]+1
否则 dp[i][j]=max(dp[i-1][j],dp[i][j-1])

9-6

比较蛋疼的语文题……
如果语文比较好几乎是裸LIS…虽说大概需要纠结一下常系数

9-7

dp[i]=min(dp[j]+1|s[j+1~i]为回文串)
并不太明显的LIS,不过不妨思考一下。
[LIS的实质是什么?我认为并非简简单单的不下降子序列。
LIS是这样一种模型:首先我们不需要用区间的方式去思考,即区间开始的位置不会对求解造成影响。其次,后一个状态与前一个状态的转移,不仅仅建立在前一个状态,还可能与之前某些状态有关。
可能你会认为这违反了最优子结构性质,其实不然。对于LIS模型来说,dp[i]始终是最优的,而前面所有状态保持其最优性并产生新的最优结构。
这里的回文串就是如此。首先,这里的区间开始位置不会对结果造成影响,而所有条件的构建,基于之前某些状态。详细的说,如果j+1到i是回文串,显然此时回文串数会在原串数基础上+1。
]
由于判断是O(n)的,所以复杂度O( n3 )。生命无法承受之慢。
于是直观的我们想到能否预处理回文串。刘书上讲的枚举终点,不过我在网上看到了这种更好的:
http://blog.csdn.net/luyuncheng/article/details/8247553
用flag[i][j]表示从i开始的长度为j的串是否为回文串。
flag[i][1]必定为回文串,而如果a[i]=a[i+1]那么flag[i][2]也是回文串。
接下来的是精髓:

for(int j=3;j<=l;++j)//长度
    for(int i=1;i<=a.size();++i)//起始点
        if(flag[i+1][j-2]&&a[i]==a[i+j-1])
            a[i][j]=1;

我们类似递推的推导:flag[i][j]为真当且仅当从i+1出发长度为j-2的串为回文串,且a[i]=a[i+j-1],这样就可以在O( n2 )预处理,总复杂度O( n2 )

9-8

题意说的有些迷…说白了就是每次能从两个栈中取出栈顶的一个元素。
i表示第一个数组的第i个元素,j为第二个的第j个
假定用L(c)表示c颜色的跨度,在满足条件的情况下,每次转移L(c)都应当+1.
现在用c[i][j]表示此时有多少是进入但未出的,于是
若i=0,c[i][j]=c[i][j-1],若有一个元素刚进入且还有则+1,若有一个元素刚出去则-1.
对j=0同理。
因此我们可以列出这样一个转移方程:
dp[i][j]表示在第一个串枚举到第i个、第二个串枚举到第j个的时候还需要多少费用。
那么若j>0,dp[i][j]=min(dp[i][j],dp[i][j-1]+c[i][j-1])
若i>0,dp[i][j]=min(dp[i][j],dp[i-1][j]+c[i-1][j])

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值