考察:计数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 }