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 */

 

posted on 2020-02-04 20:17  带你AK,带你飞  阅读(113)  评论(0编辑  收藏  举报