计算系数

计算系数

https://ac.nowcoder.com/acm/problem/16596

组合数学+快速幂

方法一:递推+打表

首先我第一眼看到的时候就隐隐约约的感觉到了一丝熟悉的味道,这不就是高中数学的组合思想嘛,然后就快速的敲了一遍,但是却忘记了组合数学的规律,组合数学和杨辉三角紧密的联系在一起!!
他的每一项系数正好是杨慧三角每一行的值,所以我们只要把杨辉三角打印出来,然后就可以快速的求解系数了,并且杨辉三角是对称的,所以最后面求解的时候n,m是不影响的,这也验证了组合数学的思想。
另外对于其他的,只需要一个快速幂就可以解决了

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1010;
const int mod = 10007;
typedef long long ll;
int dp[maxn][maxn];

ll fastpow(ll a, ll b)
{
    ll res = 1;
    while (b)
    {
        if (b & 1) //如果最后一位是1说明这个地方需要乘
            res = res * a % mod;
        a = a * a % mod; //推算乘积
        b >>= 1;         //右移去掉一位
    }
    return res;
}
int main()
{
    int a, b, k, n, m;
    while (~scanf("%d%d%d%d%d", &a, &b, &k, &n, &m))
    {
        for (int i = 0; i <= k; ++i)
            dp[i][0] = 1; //初始化
        for (int i = 1; i <= k; ++i)
            for (int j = 1; j <= i; ++j)
                dp[i][j] = (dp[i - 1][j] + dp[i - 1][j - 1]) % mod;
        ll ans = dp[k][n] % mod * fastpow(a, n) % mod * fastpow(b, m) % mod;
        printf("%lld\n", ans);
    }
    return 0;
}

方法二:递归

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define mod 10007
int dp[1010][1010];

int C(int n, int r)
{
    if (n == r || r == 0)
        return dp[n][r] = 1;
    if (dp[n][r])
        return dp[n][r];
    return dp[n][r] = (C(n - 1, r) + C(n - 1, r - 1)) % mod;
}
ll fastpow(ll a, ll b)
{
    ll res = 1;
    while (b)
    {
        if (b & 1) //如果最后一位是1说明这个地方需要乘
            res = res * a % mod;
        a = a * a % mod; //推算乘积
        b >>= 1;         //右移去掉一位
    }
    return res;
}
int main()
{
    int a, b, k, n, m;
    scanf("%d%d%d%d%d", &a, &b, &k, &n, &m);
    ll ans = fastpow(a, n) * fastpow(b, m) % mod * C(k, m) % mod;
    printf("%lld", ans);
    return 0;
}
牛客课后习题题解 文章被收录于专栏

等待蜕变

全部评论

相关推荐

评论
点赞
收藏
分享
牛客网
牛客企业服务