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])