lightoj 1145 - Dice (I)

来源:互联网 发布:js数组增加一个元素 编辑:程序博客网 时间:2024/05/27 12:21

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

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



题意:n,k,s代表有n个骰子,每个骰子有k个面,问你有多少种摆放方式使他们的和等于s。

思路:如果用dp[i][j]代表前i个骰子的和是j的方法数,那么状态转移公式应该就是dp[i][j] = dp[i-1][j-1] + dp[i-1][j-2] + .... + dp[i-1][j-k],如果这样三重循环,时间肯定爆炸,所以我们可以用前缀和来优化一下。每次加上一个,再减去一个dp[i-1][j-k],如果j-k小于0,那么dp[i-1][j-k]就是0。

还有一点就是空间也会超,所以用滚动数组。


#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#define inf 1e9#define endl '\n'#define mod 100000007#define LL long longusing namespace std;LL dp[2][15010];int main(void){    int T,n,k,s,i,j;    scanf("%d",&T);    int cas = 1;    while(T--)    {        scanf("%d%d%d",&n,&k,&s);        memset(dp,0,sizeof(dp));        dp[0][0] = 1;        int x = 1;        for(i=1;i<=n;i++)        {            x ^= 1;            LL sum = 0;            for(j=0;j<=s;j++)            {                dp[x^1][j] = sum;                if(j - k < 0)                    sum = (sum + dp[x][j])%mod;                else                    sum = ((sum + dp[x][j] - dp[x][j-k])%mod+mod)%mod;            }        }        printf("Case %d: %lld\n",cas++,dp[x^1][s]);    }}


0 0