zoukankan      html  css  js  c++  java
  • BNU 13064 Dice (I) 前缀和优化DP

    Dice (I)

     

    You have N dices; each of them has K faces numbered from 1 to K. Now you have arranged the N dices in a line. You can rotate/flip any dice if you want. How many ways you can set the top faces such that the summation of all the top faces equals S?

    Now you are given N, K, S; you have to calculate the total number of ways.

     

    Input

    Input starts with an integer T (≤ 25), denoting the number of test cases.

    Each case contains three integers: N (1 ≤ N ≤ 1000), K (1 ≤ K ≤ 1000) and S (0 ≤ S ≤ 15000).

     

    Output

    For each case print the case number and the result modulo 100000007.

     

    Sample Input

    Sample Input

    Output for Sample Input

    5

    1 6 3

    2 9 8

    500 6 1000

    800 800 10000

    2 100 10

    Case 1: 1

    Case 2: 7

    Case 3: 57286574

    Case 4: 72413502

    Case 5: 9

    Source

     
    题意:给你n个骰子,每个骰子有1-k个分数,问你多少种方式的和是S
    题解:  首先dp[i][j]表示前i个骰子,和为S的方案数
        那么 dp[i][j]=dp[i-1][j-1]+............+dp[i-1][j-k];
        对于i完全由i-1的状态得到,我们这可以用   sum[j]表示 dp[i-1][1到j]的一个前缀和,
        用i表示当前要计算的now状态,last表示i-1的状态 由此我们可以 得到dp[now][j]=sum[j-1]-sum[j-k-1];
        最终答案就是dp[now][s];
        
    ///1085422276
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<queue>
    #include<cmath>
    #include<map>
    #include<bitset>
    #include<set>
    #include<vector>
    using namespace std ;
    typedef long long ll;
    #define mem(a) memset(a,0,sizeof(a))
    #define meminf(a) memset(a,127,sizeof(a));
    #define memfy(a)  memset(a,-1,sizeof(a));
    #define TS printf("111111
    ");
    #define FOR(i,a,b) for( int i=a;i<=b;i++)
    #define FORJ(i,a,b) for(int i=a;i>=b;i--)
    #define READ(a,b,c) scanf("%d%d%d",&a,&b,&c)
    #define mod 100000007
    #define inf 100000000
    inline ll read()
    {
        ll x=0,f=1;
        char ch=getchar();
        while(ch<'0'||ch>'9')
        {
            if(ch=='-')f=-1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9')
        {
            x=x*10+ch-'0';
            ch=getchar();
        }
        return x*f;
    }
    //****************************************
    
    #define maxn 15000+5
    ll dp[2][maxn],sum[maxn];
    int n,k,s;
    int main()
    {
    
        int T=read();
        int oo=1;
        while(T--)
        {
            scanf("%d%d%d",&n,&k,&s);
              int last=0,now=1;
              mem(dp);
              dp[now][0]=1;
            for(int i=1;i<=n;i++)
            {
                swap(last,now);
                mem(dp[now]);
                sum[0]=dp[last][0];
               for(int j=1;j<=s;j++)
                {
                    sum[j]=(sum[j-1]+dp[last][j])%mod;
                }
                for(int j=1;j<=s;j++)
                {
                    if(j<=k) dp[now][j]=(sum[j-1])%mod;
                        else
                    dp[now][j]=(sum[j-1]-sum[j-k-1]+mod)%mod;
                }
            }
            printf("Case %d: ",oo++);
            cout<<dp[now][s]<<endl;;
        }
        return 0;
    }
    代码
  • 相关阅读:
    代码片段:ASCII纯数字文本数据转二进制格式
    Caffe使用CMake编译:Could Not find Boost
    Cannot uninstall '***'. It is a distutils installed project and thus we cannot accurately determine which files belong to it which would lead to only a partial uninstall.
    Ubuntu 14.04避雷系列:升级python到最新2.x版本
    过程记录:安装原版windows7
    代码片段:Shell脚本实现重复执行和多进程
    代码片段:基于STL实现的读取纯数字文本文件
    E: GPG 错误:http://developer.download.nvidia.com Release: 下列签名无效: NODATA 1 NODATA 2
    软件项目管理复习题要
    html转义字符表
  • 原文地址:https://www.cnblogs.com/zxhl/p/4908941.html
Copyright © 2011-2022 走看看