LIQ spoj – Dãy con tăng dài nhất

Nguồn đề bài: http://vn.spoj.com/problems/LIQ/

1. Đề bài LIQ Dãy con tăng dài nhất

Cho một dãy số nguyên gồm N phần tử A[1], A[2], … A[N].
Biết rằng dãy con tăng đơn điệu là 1 dãy A[i1],… A[ik] thỏa mãn
i1 < i2 < … < ik và A[i1] < A[i2] < .. < A[ik]. Hãy cho biết dãy con tăng đơn điệu dài nhất của dãy này có bao nhiêu phần tử?

Download test và solution (C/C++, Pascal) tại đây.

Input

  • Dòng 1 gồm 1 số nguyên là số N (1 ≤ N ≤ 1000).
  • Dòng thứ 2 ghi N số nguyên A[1], A[2], .. A[N] (1 ≤ A[i] ≤ 10000).

Output

Ghi ra độ dài của dãy con tăng đơn điệu dài nhất.

Ví dụ

Input:
6
1 2 5 4 6 2

Output:
4

Giải thích test ví dụ: Dãy con dài nhất là dãy A[1] = 1 < A[2] = 2 < A[4] = 4 < A[5] = 6, độ dài dãy này là 4.

Gợi ý: Sử dụng phương pháp Quy Hoạch Động. F[i]: Độ dài dãy con đơn điệu tăng dài nhất mà phần tử cuối cùng là số A[i] này.

2. Hướng dẫn LIQ SPOJ Dãy con tăng dài nhất

– Gọi F[i] là độ dài dãy con tăng dần dài nhất kết thúc tại i

– khởi tạo F[i]=1; (với i=1..n)

– F[i]=max(F[i],F[j]+1) (A[i]>A[j] ; i=1..n, j=1..i-1).

– nghiệm bài toán Max(F[i]) (i=1..n)

3. Code tham khảo LIQ SPOJ Dãy con tăng dài nhất

a. Code Pascal

const   fi='';
        nmax=1000;
type    data=longint;
var
        f:text;
        A,B:array[0..nmax+1] of data;
        n:data;

procedure docfile;
var     i,j:data;
begin
        assign(f,fi); reset(f);
        readln(f,n);
        for i:=1 to n do
                read(f,a[i]);
        close(f);
end;

function max(a,b:data):data;
begin
        if a>b then exit(a); exit(b);
end;

procedure qhd;
var     i,j,res:data;
begin
        res:=1;
        for i:=1 to n do
                begin
                        b[i]:=1;
                        for j:=1 to i-1 do
                                if A[i]>a[j] then
                                        b[i]:=max(b[i],b[j]+1);
                        res:=max(res,b[i]);
                end;
        writeln(res);
end;

begin
        docfile;
        qhd;
end.

b. code c++

#include <stdio.h>
#include <algorithm>
using namespace std;
#define nmax=1000
int n;
int a[1000], f[1000];
int main()
{
    scanf("%d",&n);
    int i,j;
    for (i=1; i<=n; i++)
    {
        scanf("%d",&a[i]);
        f[i]=1;
    }
    for (i=1; i<=n; i++)
    {
        for (j=i+1; j<=n; j++)
        {
            if (a[i]<a[j]) f[j]=max(f[i]+1,f[j]);
        }
    }
    int res=0;
    for (i=1; i<=n; i++) res=max(res,f[i]);
    printf("%d",res);
    return 0;
}

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *