1 条题解

  • 0
    @ 2025-5-4 8:52:53

    这题要求最长下降子序列的长度和个数,我们可以增加 数组maxlen[size](记录当前第1个点到第i个点之间的最长下降序列长度) 和maxnum[size](记录1~i之间的最长下降序列个数 ) ,首先对于最长下降序列属于DP基础题,只要对每一个a[i]求出符合要求(a[i] < a[j])的max( maxlen[j] + 1)即可,主要难点在第二步求下降序列总数

    在序列中,如果maxlen[j]+1 == maxlen[i]则说明a[i]和a[j]在同一个下降数列中(显然必有a[i]<a[j]),那么我们只要将每一种符合要求的状态maxnum[j]转移到maxnum[i]中就可以了,有几个细节需要注意,题目要求序列是严格递减的,那么对于两个相同的数我们只能记录一个合法解,那么程序必须只记录两个相同数之间的状态,在这里用倒推可以简化编程,只要找到一个等于的就直接跳出循环,还要注意,如果从当前的a[i]一直找到相等的a[j]在这之间都没有可行状态的话,当maxnum[i]默认值为1要修改为0(避免错误计算),为0的当然无需处理。 ———————————————— 版权声明:本文为CSDN博主「zhang360896270」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/zhang360896270/article/details/6701589

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    int a[5010],f[5010];
    struct int128
    {
    	int f[100],tot;
        void clear()//清零
        {
            for(int i=0;i<=99;i++)
                f[i]=0;
            tot=0;
        }
    	void out()//输出
    	{
    		for(int i=tot;i>=1;i--)
    			printf("%d",f[i]);
    		printf("\n");
    	}
    	int128 operator + (const int128 &a)const//重载高精加
    	{
    		int128 c;
    		c.clear();
    		c.tot=a.tot>tot?a.tot:tot;
    		int x=0;
    		for(int i=1;i<=c.tot;i++)
    		{
    			c.f[i]=a.f[i]+f[i]+x;
    			x=c.f[i]/10;
    			c.f[i]%=10;
    		}
    		if(x)c.f[++c.tot]=1;
    		return c;
    	}
    };
    int128 s[5010],num;
    int main()
    {
    	int n,ans=0;
    	scanf("%d",&n);
    	for(int i=1; i<=n; i++)
    		scanf("%d",&a[i]);
    	for(int i=1; i<=n; i++)
    	{
    		int t=0;
    		for(int j=i-1; j>=1; j--)//最长下降子序列
    			if(a[i]<a[j]&&f[j]>t)
    				t=f[j];
    		f[i]=t+1;
    		if(f[i]==1)
    			s[i].tot=s[i].f[1]=1;
    		for(int j=i-1;j>=1;j--)
    		{
    			if(a[i]<a[j]&&f[j]==t)//统计s[i]
    				s[i]=s[i]+s[j];
    			else if(a[i]==a[j]&&f[i]==f[j])//如果a[i]==a[j]&&f[i]==f[j],将s[j]清零
    				s[j].clear();
    		}
    		ans=ans>t+1?ans:t+1;
    	}
    	for(int i=1; i<=n; i++)
    		if(f[i]==ans)
    			num=num+s[i];//统计答案
    	printf("%d ",ans);
    	num.out();
    	return 0;
    }
    
    
    • 1

    信息

    ID
    953
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者