1145 - Dice (I)

1145 - Dice (I)
Time Limit: 2 second(s)Memory Limit: 32 MB

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

 


Problem Setter: Jane Alam Jan
思路:dp;
这个很容易想到N 3的思路;但是肯定GG;
那么我们需要优化。我们可以以前缀和的形式来dp;dp[i][j]表示选前i个空格,组成小与等于j大的数的种数,状态转移方程是dp[i][j]=dp[i][j-1]+dp[i-1][j-1]-dp[i-1][max(j-1-k,0)];
那么答案就是dp[x][z]-dp[x][z-1];由于内存的限制,所以我们可以用滚动数组。
 1 #include<stdio.h>
 2 #include<algorithm>
 3 #include<iostream>
 4 #include<string.h>
 5 #include<queue>
 6 #include<stack>
 7 #include<map>
 8 #include<math.h>
 9 using namespace std;
10 typedef long long LL;
11 LL dp[2][16000];
12 int main(void)
13 {
14         int i,j,k;
15         scanf("%d",&k);
16         int s;
17         int x,y,z;
18         for(s=1; s<=k; s++)
19         {
20                 memset(dp,0,sizeof(dp));
21                 scanf("%d %d %d",&x,&y,&z);
22                 printf("Case %d: ",s);
23                 if(z==0)
24                         printf("0\n");
25                 else
26                 {
27                         for(i=1; i<=y; i++)
28                         {
29                                 dp[1][i]=i;
30                         }
31                         for(i=y; i<=z; i++)
32                         {
33                                 dp[1][i]=dp[1][y];
34                         }
35                         for(i=2; i<=x; i++)
36                         {
37                                 dp[i%2][0]=0;
38                                 for(j=0; j<i; j++)
39                                         dp[i%2][j]=0;
40                                 for(j=i; j<=z; j++)
41                                 {
42                                         int cc=max(0,j-1-y);
43                                         dp[i%2][j]=dp[i%2][j-1]+dp[(i+1)%2][j-1]-dp[(i+1)%2][cc];
44                                         dp[i%2][j]%=100000007;
45                                 }
46                         }
47               printf("%lld\n",((dp[x%2][z]-dp[x%2][z-1])% 100000007+ 100000007)% 100000007);
48                 }
49         }
50         return 0;
51 }

 GG

转载于:https://www.cnblogs.com/zzuli2sjy/p/5505648.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值