• 清北学堂模拟赛d4t2 b


    分析:比较复杂的一题.

          首先要求k个mod m互不相同且和为n的数ai,我们可以转化为求和为k个bi,并且(Σbi) % m = n % m

    其中bi=ai % m,接下来可以用dp求出选了i个b,和为j的方案数.用f[i][j]表示状态.但是这样可能会让bi重复,一个解决办法是再加上一维,不过这是不必要的,我们只需要先枚举当前的数是哪一个,之后再倒序枚举i,j就可以了.我们知道b的方案数,ai = ki*m + bi,接下来知道ki的方案数就可以了.因为Σai = Σki*m + bi,所有式子全部加起来,就变成了n = (Σki) * m + Σbi,化简一下,可以得到(n - s) / m = Σki,设(n - s) / m = t,接下来的任务就是把t这个数分配给ki,这是隔板法的经典应用,假设有l个k,那么方案数就是C(l + t - 1,t - 1),最后乘上f数组.这样的话求组合数比较麻烦,还要求逆元,注意到我们前面的f[i][j]的求法是假定b1 < b2 < ...... bk的,所以有k!种排列方法,要在答案最后乘上k!,就全部转变为了乘法

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    const int maxn = 110, mod = 905229641;
    const int maxm = (maxn - 1) * maxn / 2;
    
    typedef long long ll;
    ll n, m, f[maxn][maxm], jiecheng[maxn], maxx, ans;
    
    ll C(ll a, ll b)
    {
        ll res = 1;
        for (ll i = 1; i < a; i++)
            res = res * (b + i) % mod;
        return res;
    }
    
    int main()
    {
        scanf("%lld%lld", &n, &m);
        maxx = (m - 1) * m / 2;
        f[0][0] = 1;
        for (int i = 0; i < m; i++)
            for (int j = m; j >= 0; j--)
                for (int k = maxx; k >= 0; k--)
                    if (f[j][k])
                        f[j + 1][k + i] = (f[j + 1][k + i] + f[j][k]) % mod;
        jiecheng[1] = 1;
        for (int i = 2; i <= m; i++)
            jiecheng[i] = (jiecheng[i - 1] * i) % mod;
        ll minx = n % m;
        for (ll i = minx; i <= min(n, maxx); i += m)
        {
            ll t = (n - i) / m;
            for (int j = 1; j <= m; j++)
                if (f[j][i])
                {
                ll temp = C(j, t % mod);
                temp = (temp * f[j][i]) % mod;
                temp = (temp * j) % mod;
                ans = (ans + temp) % mod;
                }
        }
        printf("%lld
    ", ans);
    
        return 0;
    }

     

  • 相关阅读:
    Java找N个数中最小的K个数,PriorityQueue和Arrays.sort()两种实现方法
    POJ 1661 Help Jimmy(C)动态规划
    LeetCode第8场双周赛(Java)
    Eclipse访问外部网站(比如:CSDN首页)
    LeetCode第151场周赛(Java)
    LeetCode第152场周赛(Java)
    Eclipse Block Selection(块选择)快捷键 Alt + Shift + A
    PAT(B) 1090 危险品装箱(Java)
    PAT(B) 1050 螺旋矩阵(Java:24分)
    PAT(B) 1045 快速排序(C)
  • 原文地址:https://www.cnblogs.com/zbtrs/p/7648080.html
Copyright © 2020-2023  润新知