Description
Solution
从高位往低位做,可以用一个很显然的DP方程:设f[i][j]表示做到第i位,有j种不同的分组,并且低于输入的有多少种。
转移显然:从上一位新增或者当前局限扩展;再把当前最大的扩展上去。
复杂度: O(n2)
Code
#include<iostream>
#include<cstdio>
#include<cstdlib>
#define fo(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
typedef long long LL;
const int N=10500,mo=1e6+7;
int read(int &n)
{
char ch=' ';int q=0,w=1;
for(;(ch!='-')&&((ch<'0')||(ch>'9'));ch=getchar());
if(ch=='-')w=-1,ch=getchar();
for(;ch>='0' && ch<='9';ch=getchar())q=q*10+ch-48;n=q*w;return n;
}
int n,ans;
int a[N],b[N];
long long f[2][N];
int main()
{
int q,w;
read(n);
fo(i,1,n)b[i]=max(b[i-1],read(a[i]));
fo(I,1,n)
{
int i=I%2;
fo(j,1,I)f[i][j]=(f[!i][j]*j%mo+f[!i][j-1])%mo;
f[i][b[I-1]]=(f[i][b[I-1]]+a[I]-1)%mo;
}
ans=0;
fo(i,1,n)ans=(ans+f[n%2][i])%mo;
printf("%d\n",ans+1);
return 0;
}