用动态规划求解的一个例题

 

 

 

问题描述:输入规模n和由n个元素组成的序列A1...An,求序列中的最长单调递增子序列的长度。

解题思路:这是一个求最优解的题目,可以采用动态规划的方法。首先,找出原始问题的最优子结构。
假设序列A1...Ai-1(i<n)是输入序列的一个子序列,其中存在一个元素Ak(k<=i-1)为A0...Ai-1中最长子序列的最后一个元素,此时对于子序列A1...Ai分两种情况,如果Ai>Ak,则A1...Ai中最长递增子序列长度为A1...Ai-1中最长子序列长度加1,否则和A1...Ai-1中最长递增子序列长度相同。如此可以得到一个递归式:设数组L1...Ln存诸子序列A1...A1,A1...A2,A1...A3,A1...An中最长递增子序列的长度,则可以得到一个递归式:

          [1                                i=1;
   L[i]=[MAX(L[1]...L[i-1])        1<i<=n,Ai<=Ak
          [MAX(L[1]...L[i-1])+1    1<i<=n,Ai>Ak

根据上式构造最优结构即最长公共子序列,代码如下:


#include <stdio.h>
#define MAXSIZE 10000
int LstSub(int A[],int n)
{
 int L[MAXSIZE],i,j,k,max;
 L[0]=1;
 for(i=1;i<n;i++)
 {
  max=0X80000000;
  for(j=0;j<i;j++)
  {
   if(L[j]>max)
   {  max=L[j]; k=j;  }
  }
  if(A[i]>A[k])
   L[i]=max+1;
  else
   L[i]=max;
 }
 return L[n-1];
}
int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        int A[MAXSIZE],i,lst;
        for(i=0;i<n;i++)
            scanf("%d",A+i);
        lst=LstSub(A,n);
        printf("%d/n",lst);
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值