[LUOGU] 1108 低价购买

统计本质不同的\(LIS\)个数。
因为本题要求的是\(N^2\)级别的算法,就直接暴力统计\(LIS\)的个数了
然后统计方案数的话加入发现有之间有一个值,以它为结尾的\(LIS\)长度和当前的相等,且和当前位置的值相等,就说明已经统计过了这个LIS,就把这个位置的\(cnt\)数组赋值成\(0\)就行了。

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <vector>
#include <bitset>
#include <cmath>
#include <queue>
#include <ctime>
#include <set>
#include <map>
#define fo(i,j,k) for(int i=j;i<=k;i++)
#define fd(i,j,k) for(int i=j;i>=k;i--)
#define go(i,k) for(int i=head[k],v=e[i].to;i;i=e[i].nxt,v=e[i].to)
using namespace std;
typedef long long ll;
typedef double db;
const int inf=0x3f3f3f3f,N=5005;
int n,a[N],f[N],cnt[N],ans,sum;
inline int rd() {
	int x=0,f=1;char ch=getchar();
	while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
	while(isdigit(ch)) x=x*10+(ch^48),ch=getchar();
	return x*f;
}
int main() {
#ifdef HSZ
	freopen(".in","r",stdin);
	freopen(".out","w",stdout);
#endif
	scanf("%d",&n);
	fo(i,1,n) a[i]=rd(),f[i]=1;
	fo(i,1,n) 
		fo(j,1,i-1) 
			if(a[i]<a[j]) f[i]=max(f[i],f[j]+1),ans=max(ans,f[i]);
	fo(i,1,n) {
		if(f[i]==1) cnt[i]=1;
		fo(j,1,i-1) 
			if(f[i]==f[j]+1&&a[i]<a[j]) cnt[i]+=cnt[j];
			else if(f[i]==f[j]&&a[i]==a[j]) cnt[i]=0;
		if(f[i]==ans) sum+=cnt[i];
	}
	cout<<ans<<' '<<sum<<endl;
	return 0;
}
posted @ 2018-10-24 07:44  SWHsz  阅读(119)  评论(0编辑  收藏  举报