zoukankan      html  css  js  c++  java
  • 动态规划专题(一) HDU1087 最长公共子序列

    Super Jumping! Jumping! Jumping!

    首先对于动态规划问题要找出其子问题,如果找的子问题是前n个序列的最长上升子序列,但这样的子问题不好,因为它不具备无后效性,因为它的第n+1的数会影响前n个序列的长度,换句话说,如果第n+1个数加上去不一定使得和前n个数加起来就是最长子序列,具体例子很多比如5,6,1,2 第5个数是3,那么最长序列5,6加3不会比1,2加3长。

    比较好的子问题是“求以K个为终点的最长上升子序列”,其实这个子问题的好处在于它限定了一点,终点为第k个数,那么我去递推第K+1的最长子序列时,它只跟前面各个以某点为终点的最长子序列有关

    接下来,我们写出它的状态转移方程

    maxLen(k)表示为ak作为终点的最长上升子序列的长度

    初始状态:maxLen(1)=1

    maxLen(k)=max{ maxLen(i):1<=i<k且ai < ak 且k>=2}+1

    若找不到则maxLen(k)=1

    因为以小于ak为终点的各序列,若满足上述条件,加上ak,一定会形成更长的上升子序列。

    另外从认识的角度讲,ak是从终点1到k-1一个个判断下来的那么一旦他们两个是上升的,连带的会把ai的最长子序列长度带上去,使之变得更长。

    本题仅作了一个小的改动最长上升总和,思路大致相同,代码如下

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #define MAXN 1005
     5 using namespace std;
     6 int num[MAXN],m[MAXN];//m记录以每个终点的最长上升总和
     7 int main()
     8 {
     9     int t,i,j,k;
    10     while(cin>>t)
    11     {
    12         if(t==0)
    13             break;
    14         memset(m,0,sizeof(0));
    15         for(i=1;i<=t;i++)
    16             scanf("%d",&num[i]);
    17         m[1]=num[1];
    18         for(i=2;i<=t;i++)
    19         {
    20             m[i]=num[i];
    21             for(j=1;j<i;j++)
    22             {
    23                 if(num[j]<num[i])
    24                     m[i]=max(m[i],m[j]+num[i]);
    25             }
    26         }
    27         k=m[1];
    28         for(i=1;i<=t;i++)
    29             k=m[i]>k?m[i]:k;
    30         cout<<k<<endl;
    31     }
    32     return 0;
    33 }
  • 相关阅读:
    设计模式系列
    Python3 系列之 可变参数和关键字参数
    设计模式系列
    【HANA系列】SAP HANA ODBC error due to mismatch of version
    【FICO系列】SAP FICO FS00修改科目为未清项目管理
    【FIORI系列】SAP OpenUI5 (SAPUI5) js框架简单介绍
    【HANA系列】SAP HANA SQL获取当前日期加若干天后的日期
    【HANA系列】SAP HANA SQL获取本周的周一
    【HANA系列】SAP HANA SQL获取当前日期
    【HANA系列】SAP HANA SQL获取当前日期最后一天
  • 原文地址:https://www.cnblogs.com/fancy-itlife/p/4336259.html
Copyright © 2011-2022 走看看