4361: isn
Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 289 Solved: 146
[Submit][Status][Discuss]
Description
给出一个长度为n的序列A(A1,A2...AN)。如果序列A不是非降的,你必须从中删去一个数,
这一操作,直到A非降为止。求有多少种不同的操作方案,答案模10^9+7。
Input
第一行一个整数n。
接下来一行n个整数,描述A。
Output
一行一个整数,描述答案。
Sample Input
4
1 7 5 3
1 7 5 3
Sample Output
18
HINT
1<=N<=2000
好题
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 const int mod=1000000007; 7 int n,cnt; 8 long long ans; 9 int a[2010],b[2010],c[2010]; 10 long long fact[2010],g[2010],num[2010][2010],f[2010][2010]; 11 void add(int tmp,int pos,long long d){ 12 for(int i=pos;i<=n;i+=i&(-i)) num[tmp][i]=(num[tmp][i]+d)%mod;//!!! 13 } 14 long long ask(int tmp,int pos){ 15 long long ret=0; 16 for(int i=pos;i;i-=i&(-i)) ret=(ret+num[tmp][i])%mod;//!!! 17 return ret; 18 } 19 int main(){ 20 scanf("%d",&n); 21 for(int i=1;i<=n;i++) scanf("%d",&a[i]),b[i]=a[i]; 22 sort(b+1,b+n+1); 23 for(int i=1;i<=n;i++) 24 if(i==1||b[i]!=b[i-1]) c[++cnt]=b[i]; 25 for(int i=1;i<=n;i++) a[i]=lower_bound(c+1,c+cnt+1,a[i])-c; 26 fact[0]=1; 27 for(int i=1;i<=n;i++) fact[i]=fact[i-1]*i%mod; 28 add(0,1,1); 29 for(int i=1;i<=n;i++) 30 for(int j=i;j>=1;j--){ 31 f[i][j]=ask(j-1,a[i])%mod; 32 add(j,a[i],f[i][j]); 33 } 34 for(int i=1;i<=n;i++) 35 for(int j=i;j<=n;j++) g[i]=(g[i]+f[j][i])%mod; 36 for(int i=1;i<=n;i++) ans=(((ans+g[i]*fact[n-i])%mod-g[i+1]*fact[n-i-1]%mod*(i+1)%mod)%mod+mod)%mod; 37 printf("%lld",ans); 38 return 0; 39 }