zoj 2136 Longest Ordered Subsequence 最长上升子序

题目地址:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2136

经典DP,划分为这样的子问题: 记录 length【k】为,以ak为最后一个元素的最长上升子序的长度,那么求这个值时,只需要取出这个数之前的比它小的数,看它的length是多少,取出有最大的length那个。

m记录的是之前子问题的length,初始化为0。


这样实现的结果就是,有length【0】就可以求出length【1】,接着可以求出length【2】......。这样暴力是 O(2^n)的问题(所有的子集都拿出来考察)就变成O(n^2)了


最后的结果是所有length中最小的那个。

#include<iostream>
using namespace std;

int main()
{
   int size;
   cin>>size;

   for(int l=0;l<size;l++)
   {
       int n;
       cin>>n;
       int *p=new int[n];
       int *length=new int[n];

       for(int i=0;i<n;i++)
          cin>>p[i];

       length[0]=1;

       for(int i=1;i<n;i++)
       {
            int m=0;     //代表之前的个数
            length[i]=1;
                 for(int j=0;j<i;j++)
               {
                   if(p[j]<p[i])
                   {
                       if(length[j]>m)
                       {
                          length[i]=length[j]+1;
                          m=length[j];
                       }
                   }

               }


       }

       int max=1;
       for(int i=0;i<n;i++)
        if(length[i]>max)  max=length[i];


       cout<<max<<endl;

      if(l<size-1)  cout<<endl;
   }
}


转载于:https://www.cnblogs.com/jingqi814/p/3581588.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值