tyvj 最长上升子序列2

来源:互联网 发布:java笔试多选题 编辑:程序博客网 时间:2024/05/16 04:47
P1208 最长上升子序列2
时间: 1000ms / 空间: 131072KiB / Java类名: Main

描述

设有整数序列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)最大不下降子序列
具有相同元素的序列,我们称之为重复序列,这里我们不统计重复序列,也即是说,重复的是算一次

输入格式

第一行为m,表示m个数(m<=900)
第二行m个数

输出格式

第一行输出最大长度n
第二行输出长度为n的序列个数Total

测试样例1

输入


1 2 2

输出


1
这道题刚开始用了map映射,并且记录了所有可能的前驱点,可是最终后5组严重超时,于是查看了一下题解,发现一开始的思路就不对,于是改成了现在这个样子。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int f[1003],a[1003],ans[1003];
int n,m,i,j,k,l,maxn;
int main()
{
scanf("%d",&n);
for (i=1;i<=n;i++)
scanf("%d",&a[i]);
f[1]=1;
for (i=2;i<=n;i++)
{
 for (j=1;j<i;j++)
   if (a[i]>a[j]&&f[i]<f[j])
    f[i]=f[j];
 f[i]++;
     }
    for (i=1;i<=n;i++)
     maxn=max(maxn,f[i]);////以上与最大上升子序列的模板完全相同
    f[n+1]=maxn+1; a[n+1]=2100000000; //在原数列的基础上加上一位,便于之后求解
    for (i=1;i<=n;i++)
     if (f[i]==1) ans[i]=1;//如果该位的最大上升子序列序列长度为1,即序列只有它本身,那么以该位为结尾的最长上升子序列个数便只有一个
    for (i=1;i<=maxn;i++)
     {
      for (j=i;j<=n;j++)
      if (f[j]==i)
      {
      k=j+1;
      while(k<=n+1&&a[j]!=a[k])//避免重复
      {
      if (a[k]>a[j]&&f[k]==f[j]+1)  ans[k]+=ans[j];//如果第K位可以由第j位推得,那么到第K位长度为I的个数就加上ans[j]
      k++;
      }
      }
     }
    printf("%d\n%d",maxn,ans[n+1]);
}
0 0