原题链接:nyoj90 整数划分
//dp代码
//dp[i][j]表示j划分为i份的次数(也叫做j的i划分)
//考虑n的m划分为a[0]+a[1]+a[2]+...+a[m]=n即dp[m][n]
//1.如果每个a[i]都大于0,令每个a[i]都减1(共减去m个1),那么a[0]+a[1]+a[2]+...+a[m]=n-m于是就转化为n-m的m划分即dp[m][n-m]
//2.如果存在a[i]=0, 那么可以删除a[i],于是就转化为n的m-1划分即dp[m-1][n]
//于是转移方程式为:dp[i][j] = dp[i][j-i] + dp[i-1][j];
#include <cstdio>
int dp[12][12];
int main(){
int T;
int n, i, j;
scanf("%d", &T);
while(T --){
scanf("%d", &n);
dp[0][0] = 1;
for(i = 1;i <= n;i ++){
for(j = 0;j <= n;j ++){
if(j - i >= 0)
dp[i][j] = dp[i - 1][j] + dp[i][j - i];
else
dp[i][j] = dp[i - 1][j];
}
}
printf("%d\n", dp[n][n]);
}
return 0;
}
//分治算法
#include <stdio.h>
int f(int n, int m) //fun(n, m)代表n的所有划分中,最大加数不大于m的划分个数
{
if(m == 1) //最大加数是1时只有一种划分
return 1;
else if(m > n) //如果m>n,则fun(n, m)=fun(n, n) 因为n的划分最大数只能是n
return f(n, n);
else if(m == n) //m=n时fun(n, m) = fun(n, m-1) + fun(n, 1) = fun(n, m-1) + 1;
return f(n, m - 1) + 1;
else // n>m时fun(n, m) = fun(n, m - 1) + fun(n - m, m) 即n的所有划分中,最大加数不大于m的划分个数 等于 最大加数不大于m - 1的划分个数 加上 加数有m的全部划分个数
return f(n, m - 1) + f(n - m, m); //f(n - m, m)就代表加数有m的全部划分个数,比如fun(6 - 3,3)有6=3+3 6=3+2+1 6=3+1+1+1 三种划分
}
int main()
{
int T, n;
scanf("%d", &T);
while(T --){
scanf("%d", &n);
printf("%d\n", f(n, n));
}
return 0;
}