第一问求最长下降子序列,不提;
第二问:借鉴了最短路的方法???
我们求出来了每个位置的最长下降子序列的长度,那么刻意这样这样转移
if f[i]==f[j]+1&&a[i]<a[j](i>j) 这代表f[i]可以由f[j]转移过来,所以 f[i]+=f[j]
但是会重复,所以当f[i]==f[j]&&a[i]==a[j] 时,说明f[j]中已经包括了f[i]中的所有转移,所以c[i]=0;
初值 当f[i]==1时,c[i]=1;
#include<iostream> #include<cstdio> #include<algorithm> #define max(a,b) a>b?a:b #define R register int using namespace std; const int N=5010; int n; int a[N],f[N],c[N]; inline int g() { R ret=0,fix=1; register char ch; while(!isdigit(ch=getchar())) fix=ch=='-'?-1:fix; do ret=(ret<<3)+(ret<<1)+(ch^48); while(isdigit(ch=getchar())); return ret*fix; } signed main() { n=g();for(R i=1;i<=n;i++) a[i]=g(); long long ans1=0,ans2=0; for(R i=1;i<=n;i++) { f[i]=1; for(R j=1;j<i;j++) if(a[i]<a[j]) f[i]=max(f[i],f[j]+1); ans1=max(ans1,f[i]); } for(R i=1;i<=n;i++) { if(f[i]==1) c[i]=1; for(R j=1;j<i;j++) if(f[i]==f[j]+1&&a[i]<a[j]) c[i]+=c[j]; else if(f[i]==f[j]&&a[i]==a[j]) c[i]=0; if(f[i]==ans1) ans2+=c[i]; } printf("%lld %lld ",ans1,ans2); }
2019.04.28