zoukankan      html  css  js  c++  java
  • 关于动态规划法的问题

    最长上升子序列(LIS)
    问题描述:设现在有一串序列,要求找出它的一串子序列,这串子序列可以不连续,但必须满足它是严格的单调递増的且为最长的。把这个长度输出。
    示例:1 7 3 5 9 4 8   结果为4
    题例:参看POJ 2533
    解法:
    1.	DP之O(n2)算法:先按DP的思想来分析一下,要想求n个数的最长上升子序列,设有数据数组data[n]和状态数组dp[n],则对其尾元素data[n]来说,它的最长上升子序列就是它自己,即dp[n]=1,而当把它的前一个元素data[n-1]考虑进来时,如果data[n-1]<data[n]则会存在一个长度为2的上升子序列,如果data[n-1]>data[n]那么这个长度仍会是1。当把这个思想一般化的时候,对于任意一个元素data[k]来说,我们需要找出在data[k]以后的元素中比data[k]大,并且最长的一个序列做为它的后继。这样dp[k]就可以写成dp[k+1]+1。现在我们定义一个量dp[k]=m,它代表着到第k个元素为止(可以包含k也可以不包含k),它的最长上升序列的长度为m。仔细体会dp[k]=m的意义,这里面的k是可包括在内,也可以不包括在内的(与之前的最大子序列和不同)。要想确定这个m的值,就必须找到一个在第k个元素之前的一个元素的值小于data[k]的值,并且那个元素所对应的dp值是找到的满足第一个条件前提下dp值最大的一个。这就意味着我们需要内层遍历之前算出来的dp值,所以需要两层循环来实现这个算法。这样我们就可以总结出状态转移方程为dp[k]=max(dp[i](1<=i<=k&&a[i]<a[k])+1。其中找dp[i]的过程我们需要用一层循环来实现,而找dp[k]的过程也要一层循环,所以我们得到了O(n2)的算法。
    dp[k]=max(dp[i])+1   其中i满足(1<=i<=k&&a[i]<a[k])
    例程:
    #include <stdio.h>
    const int inf = -0x3fffffff;
    int main(void)
    {
        int i,j,len,max,res,data[] = {1,7,3,5,9,4,8},dp[20]={1};
        len = sizeof(data)/sizeof(int);
        res = max = inf;
        for(i=1;i<len;i++)
        {
            max = inf;
            for(j=0;j<=i;j++)
                if(data[i]>data[j]&&max<dp[j])
                    max=dp[j];
            dp[i]=max+1;
            if(res<dp[i])
                搜索res = dp[i];
        }
        printf("%d
    ",res);
        return 0;
    }
    每天训练发现我比别人做的好慢,但是理解的更深刻,如果一开始学一个新知识点就搜模板,那么这样的人是走不远的,毕业之后带走的只有思维,什么荣誉,奖杯都已经不重要了。
  • 相关阅读:
    git回滚分支版本到指定版本
    java的垃圾回收
    java对象模型
    java内存模型
    偏向锁浅析
    maven打包报错:在类路径或引导类路径中找不到程序包 java.lang
    《microsoft sql server 2008技术内幕 t-sql语言基础》
    《SQL基础教程》
    内连接,外链接(左连接、右连接、全连接),交叉连接大总结+附SQL JOINS图解[转]
    《大型网站技术架构》1.大型网站架构演练
  • 原文地址:https://www.cnblogs.com/6bing/p/3931282.html
Copyright © 2011-2022 走看看