题目链接
http://acm.hdu.edu.cn/showproblem.php?pid=1028
题目大意
给出一个数字
n
,将它分解为若干个正整数之和,问有多少种方案?
比如,对于
4 = 4;
4 = 3 + 1;
4 = 2 + 2;
4 = 2 + 1 + 1;
4 = 1 + 1 + 1 + 1;
思路
很容易构造出
n
个生成函数
那么最终我们构造一个多项式 T=A(1)A(2)......A(n) ,这个多项式里 aixi 项, ai 表示的就是数字 i 拆成若干个数字和的方案数。
这个生成函数的解法可以通过FFT或者是暴力的多项式乘法实现,但是鉴于此题范围很小,下面引出一个更简单好写的做法。
可以把每个数字
T
初始时为
其实这个做法就是暴力的多项式乘法,只不过写法简化了很多而已。
代码
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#define MAXN 40020
using namespace std;
int c1[MAXN],c2[MAXN];
int num[MAXN],money[MAXN];
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
int max=0; //多项式的最高次项
for(int i=1;i<=n;i++)
{
money[i]=i;
num[i]=n/i;
}
memset(c1,0,sizeof(c1)); //c1:老多项式
memset(c2,0,sizeof(c2)); //c2:新多项式
c1[0]=1;
for(int i=1;i<=n;i++)
{
for(int j=0;j<=max;j++)
for(int k=0;k<=num[i];k++)
c2[j+k*money[i]]+=c1[j];
max+=num[i]*money[i];
memcpy(c1,c2,sizeof(c2));
memset(c2,0,sizeof(c2));
}
printf("%d\n",c1[n]);
}
return 0;
}