设有整数序列b1,b2,b3,…,bm,若存在i1<i2<i3<…<in,且bi1<bi2<bi3<…<bin,则称 b1,b2,b3,…,bm中有长度为n的不下降序列bi1,bi2,bi3,…,bin。求序列b1,b2,b3,…,bm中所有长度(n)最大不下降子序列
具有相同元素的序列,我们称之为重复序列,这里我们不统计重复序列,也即是说,重复的是算一次
输入格式 Input Format
第一行为m,表示m个数(m<=900)
第二行m个数
输出格式 Output Format
第一行输出最大长度n
第二行输出长度为n的序列个数Total
在我(与我的同学)坚持不懈的努力下终于写出来了!
program P1208;
var
f,a,num:array[0..901] of longint;
n,ans0,ans:longint;
procedure init;
var i:longint;
begin
assign(input,'P1208.in');reset(input);
assign(output,'P1208.out');rewrite(output);
fillchar(f,sizeof(f),0);
fillchar(num,sizeof(num),0);
readln(n);
for i:=1 to n do begin read(a[i]);f[i]:=1;end;
end;
procedure main;
var i,j:longint;
begin
ans:=1;ans0:=0; //最开始我用的ans:=0如果下面根本没有修改ans就一直是0所以就错了!(比如3 2 1)
for i:=2 to n do
for j:=(i-1) downto 1 do if (a[j]<a[i]) and (f[j]+1>f[i]) then begin
f[i]:=f[j]+1;
if (ans<f[i]) then ans:=f[i];
end;
writeln(ans);
a[0]:=-10000000;f[0]:=0;num[0]:=1; //用我的方法一定要加一个0点
for i:=1 to n do
for j:=(i-1) downto 0 do begin
if (a[i]=a[j]) and (f[i]=f[j]) then break; //找到第一个与i相同状态的点 前面再搜索到就一定重复了
if (a[j]<a[i]) and (f[i]=f[j]+1) then num[i]:=num[i]+num[j];
end;
for i:=1 to n do if (f[i]=ans) then ans0:=ans0+num[i];
writeln(ans0);
end;
procedure terminate;
begin
close(input);close(output);
end;
begin
init;
main;
terminate;
end.