解题报告 配饰

1.        题目

配饰(ornament)

【问题描述】

但是小L想考验一下小T,所以,他给小T出了一个难题.

他拿出了他所有的配饰并摆成两列,如果两个配饰的型号一样并且出现在不同列中,那么我们就可以认为这两个配饰为情侣配饰.另外,由于某些不为人知的原因,我们规定,在顺序选取的情况下,每选定的一对配饰必须比前面选定的一对配饰的型号要大.小T最多能够选取多少对配饰呢?

 

【输入格式】

共四行

第一行一个数N 表示第一列配饰的个数

第二行N个数 分别表示第一列配饰的型号

第三行一个数M 表示第二列配饰的个数

第四行M个数 分别表示第二列配饰的型号

 

【输出格式】

仅一个数K,表示最多能选取的情侣配饰的对数.

 

【样例输入】

5

1 4 2 6 8

5

1 5 0 2 4

 

【样例输出】

2

 

数据范围:

30%的数据 n,m<=10

70%的数据 n,m<=100

100%的数据 n,m<=5000

 

2.        算法

就是最长公共上升子序列(LCIS)的经典模型。

在这里,f[i]代表到a串的第i个数为止, 包括a[i]在内的并以a[i]为结尾的,与整个b串的最长公共上升子序列,其中max记录在a[i]>b[j]时a串的前i位与b串的前j位的LCIS,以便于下一个搜索到a[i]=b[j]时使用,此时使用的max时j之前的LCIS,把f[j]更新为max+1,这里的上一次求出的max为什么在a[i]=b[j]时也能使用呢?因为他们是相对于同一个a[i]来说的。因为a[i]<b[j]时,包括a[i]在内的LCIS不可能形成,所以不需要处理。

 

3.        注意事项

是公共上升子序列,而不是别的什么东西。

4.        代码

最长公共上升子序列(SueMiller)

var

n:longint;

a,b,f:array [1..5010] of longint;

procedure init;

var i:longint;

begin

    readln(n);

    for i:=1 to n do

      read(a[i]);

    readln;

    for i:=1 to n do

      read(b[i]);

    readln;

end;

procedure dp;

var i,j,max:longint;

begin

    fillchar(f,sizeof(f),0);

    for i:=1 to n do

    begin

      max:=0;

      for j:=1 to n do

        if (b[j]<a[i]) and (f[j]>max) then max:=f[j]

        else if (a[i]=b[j]) and (f[j]<max+1) then f[j]:=max+1;

    end;

    max:=0;

    for i:=1 to n do

      if f[i]>max then max:=f[i];

    writeln(max);

end;

begin

assign(input,'ornament.in');reset(input);

assign(output,'ornament.out');rewrite(output);

init;

dp;

close(input);close(output);

end.

 

 

 

 

 

 

原文地址:https://www.cnblogs.com/SueMiller/p/2213431.html