1 条题解

  • 2
    @ 2023-4-8 16:33:09

    如果没有每个盒子放不超过kk个的限制直接插板法求解。

    考虑dpdp

    状态设计:定义dpi,jdp_{i,j}为前ii个盒子放jj个球的方案数。

    转移:考虑第ii个盒子放几个球即可,显然第ii个盒子可以放0min(j,k)0\sim min(j,k)个取最小值是因为目前只考虑了jj个球。

    初始化dpi,0=1dp_{i,0}=1,前ii个盒子放00个球,什么都不放也算一种方案

    因此dpi,j=l=0min(i,k)dpi1,jldp_{i,j}=\sum_{l=0}^{min(i, k)}dp_{i-1,j-l}

    此时是O(k)O(k)的转移会超时。

    void solve()
    {
        cin >> n >> m >> p;
        for (int i = 0; i <= m; i++) dp[i][0] = 1;
        for (int i = 1; i <= m; i++)
        {
            for (int j = 1; j <= n; j++)
            {
                for (int k = 0; k <= min(j, p); k++)
                {
                    dp[i][j] += dp[i - 1][j - k];
                    dp[i][j] %= mod;
                }
            }
        }
        cout << dp[m][n];
    }
    

    考虑如何加速转移,发现每次都是固定iijj多增加了11,我们来研究一下dpi,jdp_{i,j}相比于dpi,j+1dp_{i,j+1}的变化。

    dpi,j=dpi1,j0+dpi1,j1+dpi1,j2++dpi1,j+1k+dpi1,jkdp_{i,j}=dp_{i - 1,j - 0}+dp_{i-1,j-1}+dp_{i-1,j-2}+\dots+dp_{i-1,j+1-k}+dp_{i-1,j-k}

    dpi,j+1=dpi1,j+1+dpi1,j+dpi1,j1++dpi1,j+2k+dpi1,j+1kdp_{i,j + 1}=dp_{i - 1,j + 1}+dp_{i-1,j}+dp_{i-1,j-1}+\dots+dp_{i-1,j+2-k}+dp_{i-1,j + 1 -k}

    可以发现首先后者比前者多了一项dpi1,j+1dp_{i-1,j+1},并且前者一直减到了dpi1,jkdp_{i-1,j-k},后者只减到了dpi1,j+1kdp_{i-1,j + 1 -k}

    因此我们维护变化的两部分结果即可。

    也就是求解新的dpi,jdp_{i,j}加上之前的dpi,j1dp_{i,j-1}以及加上没有的部分dpi1,j+1dp_{i-1,j+1},并且减去多加的部分dpi1,jkdp_{i-1,j-k}

    此时需要注意只有jkj\geq k 才需要多加dpi1,jkdp_{i-1,j-k},因为j<kj<k的时候,大家最后一项都是dpi1,0dp_{i-1,0}没有区别。

    完整代码。

    void solve()
    {
        cin >> n >> m >> p;
        for (int i = 0; i <= m; i++) dp[i][0] = 1;
        for (int i = 1; i <= m; i++)
        {
            int sum = i;//sum记录上一次dp[i][j],初始化为i,其实是因为dp[i][1]的方案数,前i个盒子放1个球,自然是i种方案
            for (int j = 1; j <= n; j++)
            {
                
                dp[i][j] = sum;
                sum = (sum + dp[i - 1][j + 1]) % mod;
                if (j - p >= 0) sum = (sum - dp[i - 1][j - p] + mod) % mod;
            }
        }
        cout << dp[m][n];
    }
    
    • 1

    信息

    ID
    357
    时间
    1000ms
    内存
    256MiB
    难度
    7
    标签
    递交数
    89
    已通过
    18
    上传者