zoukankan      html  css  js  c++  java
  • hdu 4248排列问题

    一看就可以用母函数做,不过好久没练DP了,所以还是用DP做了。用dp[i][j]表示前i种石头排出j个出来的种数,当考虑第i种石头石,枚举其使用的个数即可。WA了好几次,是整数相乘精度的问题,使用long long就过了。

    /*
     * hdu1004/win.cpp
     * Created on: 2012-7-24
     * Author    : ben
     */
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <ctime>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <set>
    #include <map>
    #include <stack>
    #include <string>
    #include <vector>
    #include <deque>
    #include <list>
    #include <functional>
    #include <numeric>
    #include <cctype>
    using namespace std;
    typedef long long LL;
    const int MAXN = 105;
    const int MAXV =10005;
    const int MOD = 1000000007;
    int nums[MAXN];
    int dp[MAXN][MAXV];
    int c[MAXV][MAXN];
    
    void InitCombineNum(){
        memset(c, 0, sizeof(c));
        for (int i = 0; i < MAXV; i++) {
            c[i][0] = 1;
        }
        c[1][1] = 1;
        for (int i = 2; i < MAXV; i++) {
            for (int j = 1; j < MAXN; j++) {
                if(j == i) {
                    c[i][j] = 1;
                    break;
                }
                c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]) % MOD;
            }
        }
    }
    
    int main() {
    #ifndef ONLINE_JUDGE
        freopen("data.in", "r", stdin);
    #endif
        int N, V, T = 0;
        InitCombineNum();
        while(scanf("%d", &N) == 1) {
            V = 0;
            for(int i = 0; i < N; i++) {
                scanf("%d", &nums[i]);
                V += nums[i];
            }
            memset(dp, 0, sizeof(dp));
            for(int i = 0; i < N; i++) {
                dp[i][0] = 1;
            }
            for(int j = 0; j <= nums[0]; j++) {
                dp[0][j] = 1;
            }
            for(int i = 1; i < N; i++) {
                for(int j = 1; j <= V; j++) {
                    LL temp = 0;
                    for(int k = 0; k <= nums[i] && k <= j; k++) {
                        temp += (((LL)dp[i - 1][j - k]) * c[j][k]) % MOD;
                    }
                    dp[i][j] = temp % MOD;
                }
            }
            LL ans = 0;
            for(int j = 1; j <= V; j++) {
                ans += dp[N - 1][j];
            }
            printf("Case %d: %d\n", ++T, (int)(ans % MOD));
        }
        return 0;
    }
  • 相关阅读:
    Mesos源码分析(8): Mesos-Slave的初始化
    OpenStack(一)——OpenStack的相关概念
    awk(gawk)文本报告生成器
    echo的色彩处理
    bash命令检测Shell脚本中的语法错误和查看详细执行过程
    Linux命令之cut
    sed流编辑器
    shell中函数的使用
    shell中的shift左移参数命令
    shell中跳出循环语句break和continue
  • 原文地址:https://www.cnblogs.com/moonbay/p/2607044.html
Copyright © 2011-2022 走看看