题目主要是计算组合数。
当遇到0时,我们先统计一共有多少连续的0,cnt个。
然后用提前维护的前缀最小值(除0外),后缀最大值(除0外),我们可以得到这串0的取值范围[maxa_i, mina_i]。
根据组合数学,从 n 个元素中可重复选取 m 个元素的选法数量为组合数 C (n + m - 1, m),其中 C (a, b) 表示从 a 个元素中选 b 个的组合数(计算公式:C (a, b) = a! / (b!・(a-b)! ))。
对答案更新 ans = ans * C (mina_i-maxa_i+1 + cnt - 1, cnt)

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e6+1100, mod = 1e9+7;
int n;
int a[N], maxa[N], mina[N];
ll fac[N], infac[N];
ll dp[1010];

ll qpow(ll x, ll y)
{
    ll ans = 1;
    x %= mod; y %= mod;
    while (y)
    {
        if (y&1) ans = ans*x%mod;
        y >>= 1;
        x = x*x%mod;
    }
    return ans;
}

ll C(ll x, ll y)
{
    return fac[x] *infac[y]%mod *infac[x-y]%mod;
}

int main()
{
    fac[0] = 1;
    for (ll i=1; i<N; ++i) fac[i] = (fac[i-1]*i)%mod;
    infac[N-1] = qpow(fac[N-1], mod-2);
    for (ll i=N-2; i>=0; --i) infac[i] = (infac[i+1]*(i+1))%mod;
    cin>>n;
    mina[0] = 1000;
    for (int i=1; i<=n; ++i)
    {
        cin>>a[i];
        if (a[i] != 0)
            mina[i] = min(mina[i-1], a[i]);
        else
            mina[i] = mina[i-1];
    }
    maxa[n+1] = 1;
    for (int i=n; i>=1; --i)
    {
        maxa[i] = max(maxa[i+1], a[i]);
    }
    ll ans = 1, cnt = 0;
    for (int i=1; i<=n; ++i)
    {
        if (a[i] == 0) cnt++;
        else if (cnt != 0)
        {
            ans = ans*C(mina[i-1]-maxa[i-1]+1+cnt-1, cnt)%mod;
            cnt = 0;
        }
    }
    if (cnt != 0)
    {
        ans = ans*C(mina[n]-maxa[n]+1+cnt-1, cnt)%mod;
        cnt = 0;
    }
    cout<<ans<<'\n';
    return 0;
}