1 条题解

  • 0
    @ 2024-1-6 11:56:02

    注意到根据要求一定存在 mex\operatorname{mex} 值为 0,1,,n10,1,\cdots,n-1 的区间。

    考虑按照 0n10\sim n-1 的顺序放数。当已经放好了 0i10\sim i-1,要放 ii 时,因为存在区间包含 0i10\sim i-1 但不包含 ii,所以 ii 必须在 0i10\sim i-1 这些数的最左边的数的左边或最右边的数的右边,于是问题相当于每次在序列左边或右边加上一个数。

    fi,jf_{i,j} 表示在区间 [i,j][i,j] 内放了 0ji0\sim j-i 的方案数即可,转移时需要注意必须存在长度为 LxL_x 的不包含 xx 的区间。

    #include<bits/stdc++.h>
    using namespace std;
    const int mod=998244353;
    
    int n,L[5001],dp[5001][5001];
    
    int main(){
        int T; scanf("%d",&T);
        while(T--){
            memset(dp,0,sizeof dp);
            bool flag=false;
            scanf("%d",&n);
            for(int i=0;i<n;i++){
                scanf("%d",L+i);
                if(L[i]<i)flag=true;
            }
            if(flag){
                printf("0\n");
                continue;
            }
            for(int i=1;i<=n;i++)
                if(i-1>=L[0]||n-i>=L[0])dp[i][i]=1;
            for(int len=1;len<n;len++){
                for(int l=1,r=len;r<=n;l++,r++){
                    dp[l][r]%=mod;
                    if(l>1&&l+L[len]-1<=n)dp[l-1][r]+=dp[l][r];
                    if(r<n&&r-L[len]+1>=1)dp[l][r+1]+=dp[l][r];
                }
            }
            printf("%d\n",dp[1][n]%mod);
        }
        return 0;
    }
    
    • 1

    信息

    ID
    8704
    时间
    1500ms
    内存
    128MiB
    难度
    5
    标签
    递交数
    3
    已通过
    1
    上传者