最长不下降子序列2(这个方法!)

设有整数序列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.

posted on 2011-10-23 22:18  ushiojamie  阅读(430)  评论(0)    收藏  举报