算法思维训练之数学题过程详解及实战演练 (2月20日)

76 阅读1分钟

开启掘金成长之旅!这是我参与「掘金日新计划·2月更文挑战」的第17天,点击查看活动详情

牛客小白月赛36 C. 杨辉三角(排列组合)

image.png

题解:

a[i]==Cn1ii=0n1i2×a[i]==i=0n1i2×Cn1ia[i] == C_{n-1}^i 即 \sum_{i = 0}^{n - 1} i^2 × a[i] == \sum_{i = 0}^{n - 1} i^2 × C_{n-1}^i

已知:i=0nCni=2n\sum_{i=0}^{n}C_n^i = 2^nkCnk=nCn1k1kC_n^k = nC_{n-1}^{k-1}

i=0n1i2×Cn1i\sum_{i = 0}^{n - 1} i^2 × C_{n-1}^i

=i=0n1i×i×Cn1i=\sum_{i = 0}^{n - 1} i × i × C_{n-1}^i

=i=0n1i×(n1)×Cn2i1= \sum_{i=0}^{n-1} i × (n-1) × C_{n-2}^{i-1}

=(n1)×i=0n1(i1+1)×Cn2i1=(n-1) × \sum_{i=0}^{n-1}(i-1+1)×C_{n-2}^{i-1}

=(n1)×i=1n=1Cn2i1+(n1)×i=1n1(i1)Cn2i1=(n-1) × \sum_{i=1}^{n=1}C_{n-2}^{i-1}+(n-1)×\sum_{i=1}^{n-1}(i-1)C_{n-2}^{i-1}

=(n1)(Cn20+Cn21+Cn22+...+Cn2n1+Cn2n2)+(n1)[(n2)Cn30+(n2)Cn31+...+(n2)Cn3n3]=(n-1)(C_{n-2}^0+C_{n-2}^1+C_{n-2}^2+...+C_{n-2}^{n-1}+C_{n-2}^{n-2}) + (n-1)[(n-2)C_{n-3}^0+(n-2)C_{n-3}^1+...+(n-2)C_{n-3}^{n-3}]

=(n1)i=0n2Cn2i+(n1)(n2)i=0n3Cn3i=(n-1)\sum_{i=0}^{n-2}C_{n-2}^{i} + (n-1)(n-2)\sum_{i=0}^{n-3}C_{n-3}^i

=(n1)2n2+(n1)(n2)2n3=(n-1)2^{n-2} + (n-1)(n-2)2^{n-3}

=(n1)(2n2+(n2)2n3)=(n-1)(2^{n-2}+(n-2)2^{n-3})

=(n1)(2n2+n2n32n2)=(n-1)(2^{n-2}+n2^{n-3}-2^{n-2})

= n(n1)2n3n(n-1)2^{n-3}

const int MOD = 99824353;
int qmi(int a, int k) {int res = 1;while (k) {if (k & 1) res = res * a % MOD;a = a * a % MOD;k >>= 1;}return res;} 
signed main() {        // a^k
   int n;
   cin >> n;
   int ans = 0;
   if (n == 1) ans = 0;
   else if (n == 2) ans = 1;
   else ans = ((n % MOD) * ((n - 1) % MOD)) % MOD * qmi(2, n - 3) % MOD;
   cout << ans << endl;
   return 0;
}

牛客小白月赛36 D. 哥三好(三维DP)

image.png

f[i][j][k]:表示ai元,bj元,ck元时,他们请客的方案数f[i][j][k]:表示a有i元,b有j元,c有k元时,他们请客的方案数

通过观察:一人一次性买三个人的单

即每个人每次给的钱:300,450,750,且均是150的倍数

所以,可以做一个预处理,都 /150。

那么分别对应,2,3,5;

下面就一顿操作,纯朴素的三维DP做法。

const int N = 110, MOD = 1000000007;
int f[N][N][N];
signed main() {  
    int a, b, c;
    cin >> a >> b >> c;
    a /= 150, b /= 150, c /= 150;
    for (int i = 0; i <= 1; i++) {
        for (int j = 0; j <= 1; j++) {
            for (int k = 0; k <= 1; k++) {
                f[i][j][k] = 1;
            }
        }
    }
    for (int i = 0; i <= a; i++) {
        for (int j = 0; j <= b; j++) {
            for (int k = 0; k <= c; k++) {
                //300,450,750
                if (i >= 2) f[i][j][k] = (f[i][j][k] + f[i - 2][j][k]) % MOD;
                if (i >= 3) f[i][j][k] = (f[i][j][k] + f[i - 3][j][k]) % MOD;
                if (i >= 5) f[i][j][k] = (f[i][j][k] + f[i - 5][j][k]) % MOD;
                
                if (j >= 2) f[i][j][k] = (f[i][j][k] + f[i][j - 2][k]) % MOD;
                if (j >= 3) f[i][j][k] = (f[i][j][k] + f[i][j - 3][k]) % MOD;
                if (j >= 5) f[i][j][k] = (f[i][j][k] + f[i][j - 5][k]) % MOD;
                
                if (k >= 2) f[i][j][k] = (f[i][j][k] + f[i][j][k - 2]) % MOD;
                if (k >= 3) f[i][j][k] = (f[i][j][k] + f[i][j][k - 3]) % MOD;
                if (k >= 5) f[i][j][k] = (f[i][j][k] + f[i][j][k - 5]) % MOD;
            }
        }
    }
    cout << f[a][b][c] % MOD << endl;
    return 0;
}