dp总结

dp总结

最近发现之前学过的很多dp优化都忘了==所以写篇文章复习一下,以备查找。

最长上升子序列(LIS)

dp方程

d[i]=maxd[k]+1(k<i,a[k]<a[i])
复杂度O(n2)

优化

因为d值相同时只需保留最小的a值,所以令g[i]d[k]==ik的最小值,显然g[1]g[2]g[k]
那么计算d[i]时,只需在g中找到最小的k使g[k]a[i],则d[i]=k,此时,a[i]g[k],所以更新g[k]=a[i]
STL中的lower_bound函数可以在O(logn)的时间内找到第一个大于等于k的数,因此复杂度可以优化到O(nlogn)
代码如下:

memset(g,0x3f,sizeof(g));
for(register int i=1;i<=n;i++)
{
    int j=lower_bound(g+1,g+n+1,a[i])-g;
    d[i]=j;
    g[j]=a[i];
}

循环部分甚至可以简写成:

for(register int i=1;i<=n;i++)d[i]=lower_bound(g+1,g+n+1,a[i])-g,g[d[i]=a[i];

应用

二维偏序分组(dilworth+lis:导弹拦截),LCS(其中一组映射成有序数列,另一组求最长上升子序列)等。

咕咕咕

喜欢 Issue Page
Error: 本文章未开启评论...
Menu