Time Limit: 2 second(s) | Memory Limit: 32 MB |
You have N dices; each of them has K facesnumbered from 1 to K. Now you have arranged the N dices ina line. You can rotate/flip any dice if you want. How many ways you can set thetop faces such that the summation of all the top faces equals S?
Now you are given N, K, S; you have to calculate thetotal 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.
题解:定义 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][j-1] = (dp[i-1][j-2] + ....+ dp[i-1][j-k]) + dp[i-1][j-k-1];
将括号部分替换掉,得
dp[i][j] = dp[i][j-1] + dp[i-1][j-1] + dp[i-1][j-k-1];(当j-k-1 < 0,dp[i-1][j-k-1] = 0)
初始条件 : dp[0][i] = 1; (0 <= i <= s)
之后滚动数组处理一下就好了.
/***********************************************
* Author: fisty
* Created Time: 2015-10-11 16:48:40
* File Name : 1145.cpp
*********************************************** */
#include <iostream>
#include <cstring>
#include <deque>
#include <cmath>
#include <queue>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <string>
#include <vector>
#include <cstdio>
#include <bitset>
#include <algorithm>
using namespace std;
#define Debug(x) cout << #x << " " << x <<endl
#define Memset(x, a) memset(x, a, sizeof(x))
const int INF = 0x3f3f3f3f;
typedef long long LL;
typedef pair<int, int> P;
#define FOR(i, a, b) for(int i = a;i < b; i++)
#define lson l, m, k<<1
#define rson m+1, r, k<<1|1
#define MAX_N 15010
#define MOD 100000007
int t;
int n, k, s;
LL dp[2][MAX_N];
int main() {
//freopen("in.cpp", "r", stdin);
//cin.tie(0);
//ios::sync_with_stdio(false);
int cnt = 1;
scanf("%d", &t);
while(t--){
scanf("%d %d %d", &n, &k, &s);
Memset(dp, 0);
for(int i = 0;i <= s; i++){
dp[0][i] = 1LL;
}
for(int i = 0;i < n; i++){
//Debug(dp[(i+1)&1][0]);
dp[(i+1)&1][0] = 0;
for(int j = 1;j <= s; j++){
if(j - k - 1 >= 0)
dp[(i+1)&1][j] = ((dp[(i+1)&1][j-1] + dp[i&1][j-1] - dp[i&1][j-k-1]) % MOD + MOD) % MOD;
else
dp[(i+1)&1][j] = (dp[(i+1)&1][j-1] + dp[i&1][j-1]) % MOD;
}
}
printf("Case %d: %lld\n",cnt++, ((dp[(n)&1][s] - dp[(n)&1][s-1]) % MOD + MOD ) % MOD);
}
return 0;
}