1 条题解

  • 0
    @ 2024-1-29 16:24:22

    考虑在排名为 xx 的数后面加一个数字 yy 后形成的数是不充分的,则新数的排名就是比它小的不充分的数的个数加 11,而比它小的不充分的数,要么是 191\sim 9,要么是由排名为 1x11\sim x-1 的数后加一个数字形成的,要么是原数加上数字 0y10\sim y-1 形成的。

    故新数的排名为 9+i=1x1(imod11)+y+19+\sum\limits_{i=1}^{x-1}(i\bmod 11)+y+1

    注意到 1x11\sim x-11111 的总和不那么好求,而若我们只关心排名对 1111 取模的结果,总和就变得很好求,即 (10+12x(x1)+y)mod11\left(10+\dfrac 12x(x-1)+y\right)\bmod 11

    考虑动态规划,记 f(i,j)f(i,j) 表示以第 ii 个数字结尾的排名模 1111jj 的不充分的数的个数,那么就可以用 f(i,j)f(i,j) 去更新 $f\left[i+1,\left(10+\dfrac 12j(j-1)+s_{i+1}\right)\bmod 11\right]$(j>si+1j > s_{i+1})。

    时间复杂度 Θ(11n)\Theta(11n)

    /**
     * @date: 2024.01.29
     * @problem: CF1142D
     * @tags: 动态规划, 数学
     */
    
    #include<bits/stdc++.h>
    using namespace std;
    
    int n,a[100001];
    string s;
    int dp[100001][11];
    // dp[i][j] means the number of numbers that 
    //   meet the requirements of the question
    //   and ending with label i and ranking module 11 as j.
    
    int main(){
        cin>>s;
        n=s.size();
        for(int i=1;i<=n;i++)a[i]=s[i-1]-'0';
        long long answer=0;
        for(int i=1;i<=n;i++){
            if(a[i])dp[i][a[i]]++;
            for(int j=0;j<=10;j++)answer+=dp[i][j];
            if(i==n)continue;
            for(int j=a[i+1]+1;j<=10;j++)
                dp[i+1][(10+a[i+1]+j*(j-1)/2)%11]+=dp[i][j];
        }
        printf("%lld\n",answer);
        return 0;
    }
    
    • 1

    信息

    ID
    2104
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者