【質問解決】Luogu P1108低価格購入

移動:自分のブログ

トピック

Luogu P1108低価格購入

回答

この問題の鍵は、計画数を計算することですが、i番目の位置の最長シーケンス長がj番目の位置から更新される場合、計画数の更新方法は同じです。番号が同じである限り、1つの位置の重複情報はクリアされます。

コード

#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