动态规划_最长上升(下降)子序列

最长上升(下降)子序列

这也是动态规划的一种经典题型,牛客网也收录了这个题(https://www.nowcoder.com/questionTerminal/585d46a1447b4064b749f08c2ab9ce66);

例1

输入:A = [157,232,6] n=3

输出:2

 

分析:

从后向前,求出以第i个元素为第一个元素时,最长上升序列的长度len[i].

初始化len[n]=1;

 

状态转移方程:len[i]=max(len[j]+1) 满足:(1) i<n (2) j = (i+1),(i+2),…,n (3)A[j]>A[i]

 

例1分析:

A = [157,232,6]n=3

(1)初始化:

len[n]=len[3]=1;

num=1;记录目前最长上升子序列的长度。

当前状态

A = [157,232,6]

len=[0,0,1]

num=1

(2)

len[2] =max (len[2+1]+1)= max (len[3]+1)=1 (由于满足A[3]>A[2],即满足6>232)

当前状态

A = [157,232,6]

len=[0,1,1]

num=1

(3)

len[1] =max(len[1+1]+1,len[1+2]+1) = max(len[2]+1,len[3]+1) (由于满足A[3]>A[1],即满足6>157)=1+1=2;

当前状态

A = [157,232,6]

len=[2,1,1]

num=2

(4)最终得出长度为2

 

JAVA代码:

public static int findLongest(int[] A, int n) {
        int[] len = new int[n+1];//记录以第i个元素为子序列的第一个元素时,最长递增子序列的长度。
        //初始化
        len[n] = 1;
        int num = 0;
        for(int i = n;i>0;i--)
        {
        	len[i]=1;
            for(int j = n;j>i;j--)
            {
                if((A[i-1]<A[j-1])&&(len[i]<=len[j]))//上升
              //if((A[i-1]>A[j-1])&&(len[i]<=len[j]))//下降
                {
                    len[i]=len[j]+1;
                    if(len[i]>num) num = len[i];
                }
            }
        }
        return num;
    }

在学习中,发现有的题还会问:方案数是多少?

这个问题问的想打人啊。。。。。。

(先把方法记录下来,刷题的时候,如果遇到了第二问,就再回来补充)

 

解决方案:

(1)对len[]排序

(2)用t[i]记录以第i个元素为第一个元素时,最长上升序列的不同方案数(注意啊,注意,是不同,需要去除重复的

(3)初始化,如果len[i]=1,则t[i]=1;

(4)关于去重:当序列中有相同的元素时,为避免重复计数,从后向前递推时,当后面的元素遇到前面的相同元素时,则不再向前推。

例:A=[2,4,1,4,5]中有最长子序列[2,4,5]和[2,4,5],但其实他们两个是同样的子序列。

 


 


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值