枚举盒子的个数,先把总数n减去掉box*k保证每个盒子至少有k个小球,剩下的小球放入盒子中可以为空,
加入box个小球保证每个盒子至少有一个小球,问题转化成不可区分小球放入不可区分盒子非空的方案数。
C[i][j]表示i个小球放入j个盒子非空的方案数,那么C[i][j] = C[i-1][j-1]+C[i-j][j],
分类:1.第j个盒子是空的,第i个小球必须放到第j个盒子中。
2.第j个盒子非空,第i个小球选一个盒子放,为了排除重复,我们注意到之前的盒子只有1层(最后一个盒子只放了一个小球),
那么先放一层减去j个小球,剩下i-j个往j个盒子里放,然后每个盒子都加一个小球,如果合法,那么至少会有2层。
对于可空的盒子,只要 把C[i-1][j-1]改成C[i][j-1]
#include<bits/stdc++.h> using namespace std; const int mod = 1e9+7; const int maxn = 1001; int C[maxn][maxn]; void GetC() { for(int i = 0; i < maxn; i++){ C[i][1] = C[i][i] = 1; for(int j = 1; j < i; j++){ C[i][j] = (C[i-1][j-1]+C[i-j][j])%mod; } } } int main() { GetC(); int T; scanf("%d",&T); while(T--){ int n,k; scanf("%d%d",&n,&k); int ans = 0; for(int box = 1,M = n/k; box <= M; box++){ ans = (ans + C[n-box*k+box][box])%mod; } printf("%d ",ans); } return 0; }