hdu 1028(普通型母函数)

Ignatius and the Princess III

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 6546    Accepted Submission(s): 4625


Problem Description
"Well, it seems the first problem is too easy. I will let you know how foolish you are later." feng5166 says.

"The second problem is, given an positive integer N, we define an equation like this:
  N=a[1]+a[2]+a[3]+...+a[m];
  a[i]>0,1<=m<=N;
My question is how many different equations you can find for a given N.
For example, assume N is 4, we can find:
  4 = 4;
  4 = 3 + 1;
  4 = 2 + 2;
  4 = 2 + 1 + 1;
  4 = 1 + 1 + 1 + 1;
so the result is 5 when N is 4. Note that "4 = 3 + 1" and "4 = 1 + 3" is the same in this problem. Now, you do it!"
 

Input
The input contains several test cases. Each test case contains a positive integer N(1<=N<=120) which is mentioned above. The input is terminated by the end of file.
 

Output
For each test case, you have to output a line contains an integer P which indicate the different equations you have found.
 

Sample Input
  
  
4 10 20
 

Sample Output
  
  
5 42 627
 

Author
Ignatius.L
 



题目类型:普通型母函数

题目描述:问整数拆分有多少种形式

题目分析:


母函数又名生成函数,对于数列{ A(n) } n >= 0,∑(k>=0) A(k) * X^k = A(0)  + A(1) * X^1 + A(2) * X^2 +……+ A(k) * X ^ k
为数列{A(n)}的普通型母函数,简称普母函数。


记多重集 X = { n1x1, n2x2,……,nnxn}, x1,x2,x3,x4,……xn表示n个不同的元素。 ni(  1<= i <= n)为正整数或无穷,ni表示元素xi在计数问题中可取的最多的重数(无穷表示可取重数不受限制),称  X = { n1x1, n2x2,……,nnxn} 为 x1,x2,x3,....,xn的多重集。


对于类似于多重集计数问题的组合问题,可以用普母函数来解决。
多重集中的每个元素,导出一个相应的母函数。比如  nixi, ni = 2 xi = 4.那么相应的母函数G(x) = 1 + x ^ 4 + x ^ 8
然后把生成的所有母函数相乘,即可求解问题。

模拟多项式相乘的时候,可以用 a[i] 的值 表示 x^i 的系数。 那么 c * x^i  * d * x^j  就相当于 a[i] * b[j] ,结果为 r[i+j] = a[i] * b[j]。


代码如下:


#include <stdio.h>
#include <memory.h>
#define N 121

int result[N];
int temp[N];

void init(){
    int i,j,k;
    memset(result,0,sizeof(result));
    memset(temp,0,sizeof(temp));
    for( i = 0; i < N; i++) {
        result[i] = 1;
    }
    for( k = 2; k < N; k++){
        for( i = 0; i < N; i++){
            for( j = 0; j < N; j += k) {
                if( result[i] != 0 && i + j < N) {
                    temp[i+j] += result[i];
                }
            }
        }
        for( i = 0; i < N; i++){
            result[i] = temp[i];
            temp[i] = 0;
        }
    }
}


int main()
{
    init();
    int n;
    while(scanf("%d",&n) != EOF) {
        printf("%d\n",result[n]);
    }


    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值