【题解】洛谷P1108 低价购买

前往:我自己搭建的博客

题目

洛谷P1108低价购买

题解

此题关键在于计算方案数,如果第i个位置的最长序列长度是由第j个位置更新而来的,则方案数更新方法相同。去重只要当数字相同时,清空其中一个位置的重复信息。

代码

#include <bits/stdc++.h>
using namespace std;
const int maxn=5e3+5;
int n;
int a[maxn],f[maxn],cnt[maxn]; 
//f[i]表示以a[i]结尾的单调数列的最长长度,cnt[i]表示以a[i]结尾的长度为f[i]的数列的个数 
inline void dp()
{
	int ans1=0;
	for(int i=1;i<=n;i++)
	{
		f[i]=1; //初始化 
		for(int j=1;j<i;j++)
			if(a[i]<a[j]) f[i]=max(f[i],f[j]+1);
		ans1=max(ans1,f[i]);
	}
	printf("%d ",ans1);
	for(int i=1;i<=n;i++)
	{
		if(f[i]==1) cnt[i]=1; //初始化 
		for(int j=1;j<i;j++) 
		{
			if(a[i]==a[j]) cnt[i]=0; //去重 
			cnt[i]+=cnt[j]*(f[i]==f[j]+1&&a[i]<a[j]);
		}
	}
	int ans2=0; for(int i=1;i<=n;i++) ans2+=cnt[i]*(f[i]==ans1);
	printf("%d\n",ans2);
}

int main()
{
	scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]);
	dp();
	
	return 0;
}

猜你喜欢

转载自blog.csdn.net/zjgmartin/article/details/108561291