最长上升子序列

最长上升子序列

标签(空格分隔): ACM题目 动态规划


POJ_百练_2757:最长上升子序列

描述
一个数的序列 bi b i ,当 b1<b2<...<bS b 1 < b 2 < . . . < b S 的时候,我们称这个序列是上升的。对于给定的一个序列 (a1,a2,...,aN) ( a 1 , a 2 , . . . , a N ) ,我们可以得到一些上升的子序列 (ai1,ai2,...,aiK) ( a i 1 , a i 2 , . . . , a i K ) ,这里 1<=i1<i2<...<iK<=N 1 <= i 1 < i 2 < . . . < i K <= N 。比如,对于序列 (1,7,3,5,9,4,8) ( 1 , 7 , 3 , 5 , 9 , 4 , 8 ) , 有它的一些上升子序列,如 (1,7),(3,4,8) ( 1 , 7 ) , ( 3 , 4 , 8 ) 等等。这些子序列中最长的长度是 4 4 ,比如子序列(1,3,5,8).

你的任务,就是对于给定的序列,求出最长上升子序列的长度。

输入

输入的第一行是序列的长度N (1 <= N <= 1000)。第二行给出序列中的N个整数,这些整数的取值范围都在0到10000。

输出

最长上升子序列的长度。

样例输入

7
1 7 3 5 9 4 8

样例输出
4

来源

翻译自 Northeastern Europe 2002, Far-Eastern Subregion 的比赛试题

问题建模:

输入:
N,N[1,1000] N , N ∈ [ 1 , 1000 ] 代表序列的长度
a(i),i[1,N] a ( i ) , i ∈ [ 1 , N ] 代表序列中第 i i 个元素的值

输出:
ans代表序列中最长子序列的长度.

找子问题:
“求序列的前 n n 个元素的最长上升子序列的长度”是和原问题相同的一个子问题,但是不具有”无后效性”.
假设F(n)=x, 但可能前 n n 个元素中有多个序列满足F(n)=x,比如前 n n 个元素中有序列B1,B2,B3,的长度均为 x x ,即都满足F(n)=x,那么可能序列 B1 B 1 中的最后一个元素比 an+1 a n + 1 大,那么此时 F(n+1)=x+1 F ( n + 1 ) = x + 1 ,也有可能 B2 B 2 中的最后一个元素不比 a(n+1) a ( n + 1 ) 小,那么 F(n+1)=x F ( n + 1 ) = x ,也就是说计算 F(n+1) F ( n + 1 ) 的时候我需要知道计算 F(n) F ( n ) 时候的得到的所有序列.这显然是不满足无后效性的设计.

满足无后效性的设计要求: 计算第 n+1 n + 1 个状态的时候,也就是计算 F(n+1) F ( n + 1 ) 的时候,我只需要知道 F(n) F ( n ) ,但是不需要知道计算第 n n 个状态的时候的计算过程.计算第n个状态的计算过程和计算第 n+1 n + 1 个状态无关.

好的设计方法
考虑”以第 k k 个元素作为终点计算得到最长上升子序列的长度”.这个子问题的形式和原问题并不完全一样.但是它的状态的计算是满足无后效性原则的.求出以第k,k[1,N]个元素作为终点的最长上升子序列长度,在这 n n 个状态中找到最大的值便是原问题的解.

递推方程:
maxLen(k): k k 作为终点的最长上升子序列的长度.
maxLen(1)=1
maxLen(k)=0,k[2,N] m a x L e n ( k ) = 0 , k ∈ [ 2 , N ]
计算,当 k[2,N] k ∈ [ 2 , N ] 时有:

maxLen(k)={max{maxLen(k),maxLen(i)+1},max{maxLen(k),1},if a(k)>a(i)if a[k]a[i]i[1,k1] m a x L e n ( k ) = { max { m a x L e n ( k ) , m a x L e n ( i ) + 1 } , if  a ( k ) > a ( i ) max { m a x L e n ( k ) , 1 } , if  a [ k ] ≤ a [ i ] i ∈ [ 1 , k − 1 ]

ans=max1kN{maxLen(k)} a n s = max 1 ≤ k ≤ N { m a x L e n ( k ) }

实例计算:

N=7 N = 7
a1=1,a2=7,a3=3,a4=5,a5=9,a6=4,a7=8 a 1 = 1 , a 2 = 7 , a 3 = 3 , a 4 = 5 , a 5 = 9 , a 6 = 4 , a 7 = 8

代入递推公式计算 maxLen(k),k[1,N] m a x L e n ( k ) , k ∈ [ 1 , N ]
maxLen(1)=1 m a x L e n ( 1 ) = 1

计算以第二个元素作为终点的最长序列长度:

maxLen(2)=0 m a x L e n ( 2 ) = 0
maxLen(2)1=max{maxLen(2),maxLen(1)+1}=2,a(2)>a(1) m a x L e n ( 2 ) 1 = max { m a x L e n ( 2 ) , m a x L e n ( 1 ) + 1 } = 2 , a ( 2 ) > a ( 1 ) 成 立
maxLen(2)=2 m a x L e n ( 2 ) = 2

计算以第三个元素作为终点的最长序列长度:

maxLen(3)=0 m a x L e n ( 3 ) = 0
maxLen(3)1=max{maxLen(3),maxLen(1)+1}=2,a(3)>a(1) m a x L e n ( 3 ) 1 = max { m a x L e n ( 3 ) , m a x L e n ( 1 ) + 1 } = 2 , a ( 3 ) > a ( 1 ) 成 立
maxLen(3)=2 m a x L e n ( 3 ) = 2
maxLen(3)2=max{maxLen(3),1}=2,a(3)a(2) m a x L e n ( 3 ) 2 = max { m a x L e n ( 3 ) , 1 } = 2 , a ( 3 ) ≤ a ( 2 ) 成 立
maxLen(3)=2 m a x L e n ( 3 ) = 2

计算以第四个元素作为终点的最长序列长度:

maxLen(4)=0 m a x L e n ( 4 ) = 0
maxLen(4)1=max{maxLen(4),maxLen(1)+1}=2,a(4)>a(1) m a x L e n ( 4 ) 1 = max { m a x L e n ( 4 ) , m a x L e n ( 1 ) + 1 } = 2 , a ( 4 ) > a ( 1 ) 成 立
maxLen(4)=2 m a x L e n ( 4 ) = 2
maxLen(4)2=max{maxLen(4),1}=2,a(4)a(2) m a x L e n ( 4 ) 2 = max { m a x L e n ( 4 ) , 1 } = 2 , a ( 4 ) ≤ a ( 2 ) 成 立
maxLen(4)=2 m a x L e n ( 4 ) = 2
maxLen(4)3=max{maxLen(4),maxLen(3)+1}=3,a(4)>a(3) m a x L e n ( 4 ) 3 = max { m a x L e n ( 4 ) , m a x L e n ( 3 ) + 1 } = 3 , a ( 4 ) > a ( 3 ) 成 立
maxLen(4)=3 m a x L e n ( 4 ) = 3

计算以第五个元素作为终点的最长序列长度:

maxLen(5)=0 m a x L e n ( 5 ) = 0
maxLen(5)1=max{maxLen(5),maxLen(1)+1}=2,a(5)>a(1) m a x L e n ( 5 ) 1 = max { m a x L e n ( 5 ) , m a x L e n ( 1 ) + 1 } = 2 , a ( 5 ) > a ( 1 ) 成 立
maxLen(5)=2 m a x L e n ( 5 ) = 2
maxLen(5)2=max{maxLen(5),maxLen(2)+1}=3,a(5)>a(2) m a x L e n ( 5 ) 2 = max { m a x L e n ( 5 ) , m a x L e n ( 2 ) + 1 } = 3 , a ( 5 ) > a ( 2 ) 成 立
maxLen(5)=3 m a x L e n ( 5 ) = 3
maxLen(5)3=max{maxLen(5),maxLen(3)+1}=3,a(5)>a(3) m a x L e n ( 5 ) 3 = max { m a x L e n ( 5 ) , m a x L e n ( 3 ) + 1 } = 3 , a ( 5 ) > a ( 3 ) 成 立
maxLen(5)=3 m a x L e n ( 5 ) = 3
maxLen(5)4=max{maxLen(5),maxLen(4)+1}=2,a(5)>a(4) m a x L e n ( 5 ) 4 = max { m a x L e n ( 5 ) , m a x L e n ( 4 ) + 1 } = 2 , a ( 5 ) > a ( 4 ) 成 立
maxLen(5)=4 m a x L e n ( 5 ) = 4

计算以第六个元素作为终点的最长序列长度:

maxLen(6)=0 m a x L e n ( 6 ) = 0
maxLen(6)1=max{maxLen(6),maxLen(1)+1}=2,a(6)>a(1) m a x L e n ( 6 ) 1 = max { m a x L e n ( 6 ) , m a x L e n ( 1 ) + 1 } = 2 , a ( 6 ) > a ( 1 ) 成 立
maxLen(6)=2 m a x L e n ( 6 ) = 2
maxLen(6)2=max{maxLen(6),1}=2,a(6)a(2) m a x L e n ( 6 ) 2 = max { m a x L e n ( 6 ) , 1 } = 2 , a ( 6 ) ≤ a ( 2 ) 成 立
maxLen(6)=2 m a x L e n ( 6 ) = 2
maxLen(6)3=max{maxLen(6),maxLen(3)+1}=3,a(6)>a(3) m a x L e n ( 6 ) 3 = max { m a x L e n ( 6 ) , m a x L e n ( 3 ) + 1 } = 3 , a ( 6 ) > a ( 3 ) 成 立
maxLen(6)=3 m a x L e n ( 6 ) = 3
maxLen(6)4=max{maxLen(6),1}=3,a(6)a(4) m a x L e n ( 6 ) 4 = max { m a x L e n ( 6 ) , 1 } = 3 , a ( 6 ) ≤ a ( 4 ) 成 立
maxLen(6)=3 m a x L e n ( 6 ) = 3
maxLen(6)5=max{maxLen(6),1}=3,a(6)a(5) m a x L e n ( 6 ) 5 = max { m a x L e n ( 6 ) , 1 } = 3 , a ( 6 ) ≤ a ( 5 ) 成 立
maxLen(6)=3 m a x L e n ( 6 ) = 3

计算以第七个元素作为终点的最长序列长度:

maxLen(7)=0 m a x L e n ( 7 ) = 0
maxLen(7)1=max{maxLen(7),maxLen(1)+1}=2,a(7)>a(1) m a x L e n ( 7 ) 1 = max { m a x L e n ( 7 ) , m a x L e n ( 1 ) + 1 } = 2 , a ( 7 ) > a ( 1 ) 成 立
maxLen(7)=2 m a x L e n ( 7 ) = 2
maxLen(7)2=max{maxLen(7),maxLen(2)+1}=3,a(7)>a(2) m a x L e n ( 7 ) 2 = max { m a x L e n ( 7 ) , m a x L e n ( 2 ) + 1 } = 3 , a ( 7 ) > a ( 2 ) 成 立
maxLen(7)=3 m a x L e n ( 7 ) = 3
maxLen(7)3=max{maxLen(7),maxLen(3)+1}=3,a(7)>a(3) m a x L e n ( 7 ) 3 = max { m a x L e n ( 7 ) , m a x L e n ( 3 ) + 1 } = 3 , a ( 7 ) > a ( 3 ) 成 立
maxLen(7)=3 m a x L e n ( 7 ) = 3
maxLen(7)4=max{maxLen(7),maxLen(4)+1}=4,a(7)>a(4) m a x L e n ( 7 ) 4 = max { m a x L e n ( 7 ) , m a x L e n ( 4 ) + 1 } = 4 , a ( 7 ) > a ( 4 ) 成 立
maxLen(7)=4 m a x L e n ( 7 ) = 4
maxLen(7)5=max{maxLen(7),1}=4,a(7)a(5) m a x L e n ( 7 ) 5 = max { m a x L e n ( 7 ) , 1 } = 4 , a ( 7 ) ≤ a ( 5 ) 成 立
maxLen(7)=4 m a x L e n ( 7 ) = 4
maxLen(7)6=max{maxLen(7),maxLen(6)+1}=4,a(7)>a(6) m a x L e n ( 7 ) 6 = max { m a x L e n ( 7 ) , m a x L e n ( 6 ) + 1 } = 4 , a ( 7 ) > a ( 6 ) 成 立
maxLen(7)=4 m a x L e n ( 7 ) = 4

maxLen(1)=1,maxLen(2)=2,maxLen(3)=2, m a x L e n ( 1 ) = 1 , m a x L e n ( 2 ) = 2 , m a x L e n ( 3 ) = 2 ,
maxLen(4)=3,maxLen(5)=4,maxLen(6)=3,maxLen(7)=4 m a x L e n ( 4 ) = 3 , m a x L e n ( 5 ) = 4 , m a x L e n ( 6 ) = 3 , m a x L e n ( 7 ) = 4
ans=4 a n s = 4

算法时间复杂度: O(N2) O ( N 2 )

轻松ACCCEPT:

CODE: C O D E :

// http://bailian.openjudge.cn/practice/2757
#include <bits/stdc++.h>

using namespace std;

#define MAX_N 1005
int N;
int a[MAX_N], maxLen[MAX_N];

void solve(){
    int i,k;
    for(i = 1; i <= N; i++) maxLen[i] = 1; // 一开始都是1
    for(k = 2; k <= N; k++){ // 以第k个元素作为终点
        for(i = 1; i <= k-1; i++){ // 前面
            if(a[k] > a[i]) { // 递推公式
                maxLen[k] = max(maxLen[k], maxLen[i]+1);
            }
        }
    }
    printf("%d\n", *max_element(maxLen+1, maxLen+N+1));
}

int main(){
    //freopen("in.txt", "r", stdin);
    int i;
    while(~scanf("%d", &N) && N){
        for(i = 1; i <= N; i++) scanf("%d", &a[i]); // 输入数据
        solve();
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值