整数N分解,搭积木,离散数学中的母函数,ZOJ(1163)

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1163

解题报告:

将整数N分解为:两个及以上的不重复的整数,最流行的解法是动态规划,和生成函数(01背包思路)。

 

将问题看成经典的搭积木的问题。相当与求:将N块积木搭成J排.

f[i,j] = f[i,j-1]+ f[i-j,j-1];

初始化f[0,0] = 1;

即求f[N,N] - 1;(两个及以上的)

#include <stdio.h>
#include <algorithm>
#include <string.h>
#define MAX 505

using namespace std;

long long dp[MAX][MAX];

int main()
{
    /*memset(dp,0,sizeof(dp));
    dp[0] = 1;
    for(int i=1; i<MAX; i++)
        for(int j=MAX-1; j>=i; j--)
            dp[j] += dp[j-i];*/

    int n;
    dp[0][0]=1;

    for(int i=0; i<MAX; i++)
    {
        for(int j=1; j<=i; j++)
            dp[i][j]=dp[i][j-1]+dp[i-j][j-1];

        for(int j=i+1; j<MAX; j++)
            dp[i][j]=dp[i][i];
    }

    while(scanf("%d",&n),n)
        printf("%lld\n",dp[n][n]-1);

    return 0;
}

 

 

生成函数算法,这里的知识是离散数学中的母函数。

G(X) = (1+X)(1+X^2)(1+X^3)***(1+X^N);

这里可以看出x^3的系数为 X*X^2, 和X^3,因为这里的拆数是拆成两个及以上,所以减去X^3,及要减1;

f[j]表示x^j的系数,那么计算x^j的系数,是要累加的,这里采用01背包,f[j] += f[j-i];(i=1~0(j=i))

 

memset(dp,0,sizeof(dp));
dp[0] = 1;
for(int i=1; i<MAX; i++)
    for(int j=MAX-1; j>=i; j--)
        dp[j] += dp[j-i];
printf("%d\n",dp[n]-1);

 

转载于:https://www.cnblogs.com/TreeDream/p/5535861.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值