/*
初学母函数,练练手;
*/
母函数解:
/*
求整数n的整数拆分方法;
题目理解为:将数字1、2、3、……n;每个数字可以选取无限次,求能组成n的情况总数
函数 (1+x+x^2+x^3……)(1+x^2+x^4……)(1+x^3+x^6+x^9……) ……
第一项的意义是:取0个1,取1个1、2个1,3个1……第二项的意义是:取0个2,取1个2……
以此类推 ;
每个括号为一个大项,我们先将第一大项和第二大项乘起来,得到结果和第三项相乘……
以此类推;
*/
#include <iostream>
using namespace std;
int a[200],b[200]; //a[]存放结果中x^i的系数,即代表整数i的划分情况数,b[]临时存放系数
int main()
{
int n;
while(cin>>n&&n!=0)
{
for(int i = 0; i <= n; i++)
{
a[i] = 1; //第一个表达式中的面值组合都是1,所以下面的是从第二个表达式开始
b[i] = 0;
}
for(int i = 2; i <= n; i++) // 循环两大项两大项相乘
{
for(int j = 0; j <= n; j++)
for(int k = 0; k+j <= n; k+=i)
{
b[j+k] += a[j];
}
for(int j = 0; j <= n; j++) //将b[]存至a[],b[]置零
{
a[j] = b[j];
b[j] = 0;
}
}
cout<<a[n]<<endl;
}
}
完全背包解:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
using namespace std;
int dp[120];
int main()
{
int n;
while(cin>>n&&n!=0)
{
memset(dp,0,sizeof(dp));
dp[0] = 1;
for(int i = 1; i<=n; i++)
for(int j = i; j <= n; j++)
{
dp[j] += dp[j-i];
}
cout<<dp[n]<<endl;
}
}