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;
这个很容易想到N3的思路;但是肯定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 "); 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 ",((dp[x%2][z]-dp[x%2][z-1])% 100000007+ 100000007)% 100000007); 48 } 49 } 50 return 0; 51 }
GG