原题链接

考察:计数dp

错误思路:

       以最后一个数来划分...f[i][j]表示选i个数,总能量为j的方案数 f[i][j] +=f[i-1][j-k](0<=k<=j)k表示最后一个数是k.

此思路错在会计重.

正确思路:

       按照集合中最小的数是0和>0来划分.f[i][j]表示和为i,数个数为j的方案数. f[i][j] = f[i][j-1](去掉最小数0)+f[i-j][j](把每个数减去1).此思路不会计重因为最小数0 1和1 0都是同一类集合.由f[0][1]推导来,和为0视为一种方法.

 1 #include <iostream>
 2 #include <cstring>
 3 #include <algorithm>
 4 using namespace std;
 5 const int N = 15;
 6 int m,n,f[N][N];
 7 int main()
 8 {
 9     int T;
10     scanf("%d",&T);
11     while(T--)
12     {
13         scanf("%d%d",&m,&n);
14         memset(f,0,sizeof f);
15         for(int i=1;i<=n;i++) f[0][i] = 1;
16         for(int i=1;i<=m;i++)
17           for(int j=1;j<=n;j++)
18           {
19               f[i][j] +=f[i][j-1]; 
20               if(i>=j) f[i][j] +=f[i-j][j];
21           }
22         printf("%d\n",f[m][n]);
23     }
24     return 0;
25 }