题意:
给你一个数组,这个数组是单调不增的,但是有些位置的数丢失了,现在问你合法的数组一共有多少个,对1e9+7取模。同时数组中的每个数都是1到1000。
思考:
刚开始看着像dp,感觉不太好做,其实呢主要是还是对球和盒子问题不太熟悉。这个题就是球和盒子问题,比如9 0 0 7,那么可以放的数是9 8 7,一共3个,然后有两个0也就是2个球,那么就是2个求放到3个盒子里,盒子可以空,问你有多少种放法。这就是球和盒子的经典问题C(n+m-1,m-1)。
代码:
int T,n,m,k;
int va[N];
int fact[N],infact[N];
int ksm(int a,int b)
{
int sum = 1;
while(b)
{
if(b&1) sum = sum*a%mod;
a = a*a%mod;
b >>= 1;
}
return sum;
}
void init(int x)
{
fact[0] = infact[0] = 1;
for(int i=1;i<=x;i++) fact[i] = fact[i-1]*i%mod;
infact[x] = ksm(fact[x],mod-2)%mod; //注意这里,这样求infact会少很多ksm,时间会更快
for(int i=x-1;i>=1;i--) infact[i] = infact[i+1]*(i+1)%mod;
}
int C(int a,int b)
{
if(a<b) return 0;
return fact[a]*infact[b]%mod*infact[a-b]%mod;
}
signed main()
{
IOS;
init(1e6+2000);
cin>>n;
for(int i=1;i<=n;i++) cin>>va[i];
va[n+1] = 1;
int l = 1000,res = 0,ans = 1;
for(int i=1;i<=n+1;i++)
{
if(va[i]==0)
{
res++;
continue;
}
int can = l-va[i]+1;
ans = ans*C(can+res-1,can-1)%mod;
l = va[i];
res = 0;
}
cout<<ans%mod;
return 0;
}
总结:
多多思考和总结。