zoukankan      html  css  js  c++  java
  • HDU-4248 A Famous Stone Collector 组合数学 DP

    HDU 4248

    题意:

    给定n种颜色不同的石子,每种石头有 num[i] 个。从中取石子,问能够得到多少种不同的序列。

    [n leq 100,num[i]leq 100 ]

    数据范围比较小,考虑dp

    [dp[i][j]表示选前i种石头,且选的石头总数为j时的不同序列个数 ]

    有转移方程

    [dp[i][j] = sum dp[i - 1][j - k] cdot binom{j}{k} quad kleq num[i] ]

    即考虑第i种石头的贡献,也就是第j个中选k个位置给第i种石头。

    [ans = sum dp[n][i]quad i leq sum ]

    ll C[10015][105];
    
    void init() {
        for (int i = 0; i < 10015; i++) {
            C[i][0] = 1;
            for (int j = 1; j <= i && j <= 105; j++)
                C[i][j] = (C[i - 1][j - 1] + C[i - 1][j]) % MOD;
        }
    }
    
    int num[105];
    ll dp[105][10005];
    
    int main() {
        int n;
        init();
        int kase = 1;
        while (~scanf("%d", &n)) {
            ll sum = 0;
            for (int i = 1; i <= n; i++) num[i] = readint();
            memset(dp, 0, sizeof dp);
            dp[0][0] = 1;
            for (int i = 1; i <= n; i++) {
                sum += num[i];
                for (int j = 0; j <= sum; j++) {
                    for (int k = 0; k <= num[i] && j >= k; k++)
                        dp[i][j] += dp[i - 1][j - k] * C[j][k], dp[i][j] %= MOD;
                }
            }
            ll res = 0;
            for (int i = 1; i <= sum; i++) res += dp[n][i], res %= MOD;
            printf("Case %d: ", kase++);
            Put(res);
            puts("");
        }
    }
    
  • 相关阅读:
    384. 最长无重复字符的子串
    406. 和大于S的最小子数组
    159. 寻找旋转排序数组中的最小值
    62. 搜索旋转排序数组
    20. 骰子求和
    125. 背包问题 II
    92. 背包问题
    1295. 质因数统计
    471. 最高频的K个单词
    1339. 最大区间
  • 原文地址:https://www.cnblogs.com/hznumqf/p/13534497.html
Copyright © 2011-2022 走看看