1 #include <iostream> 2 #include <cstdio> 3 4 using namespace std; 5 // 有关计数问题的dp 6 // 有n个无区别的物品,划分成不超过m组,求方法数取模M的余数 7 8 const int max_n=1000+2; 9 const int max_m=1000+2; 10 const int max_M=10000+2; 11 12 int n,m,M; 13 int dp[max_M][max_M]; 14 15 // 定义dp[i][j] 16 // 考虑dp[i][j-i],将dp[i][j-i]中所有划分(包括省略的0)+1,即得到新的满足要求的划分,且每一个划分最少是1 17 // 另外,考虑可能有空划分的情况,这种情况,在dp[i-1][j]中已全部包含(考虑到递推定义过程) 18 19 void solve() 20 { 21 dp[0][0]=1; 22 for(int i=1;i<=m;++i) 23 { 24 for(int j=0;j<=n;++j) 25 { 26 if(j-i>=0) 27 { 28 dp[i][j]=(dp[i-1][j] + dp[i][j-i]); 29 } 30 else 31 { 32 dp[i][j]=dp[i-1][j]; 33 } 34 // printf("%d ",dp[i][j]); 35 } 36 // printf("\n"); 37 } 38 39 printf("%d\n",dp[m][n]); 40 } 41 42 int main() 43 { 44 scanf("%d %d %d",&n,&m,&M); 45 solve(); 46 return 0; 47 } 48 /* test 49 4 3 10000 50 51 ans=4(1+1+2=1+3=2+2=4) 52 */