hdu1028:整数拆分

求整数的拆分数。。

一种解法是母函数

#include <iostream>
#include <stdio.h>
#include<string.h>
#include<algorithm>
#include<string>
#include<ctype.h>
using namespace std;
#define MAXN 10000
int dp[2][130];
int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        memset(dp,0,sizeof(dp));
        dp[0][0]=1;
        for(int i=1;i<=n;i++)
        {
            for(int j=0;j<=n;j++)
            {
                for(int k=0;j+k*i<=n;k++)
                {
                    dp[i%2][j+k*i]+=dp[(i-1)%2][j];
                }
                dp[(i-1)%2][j]=0;
            }
        }
        printf("%d\n",dp[n%2][n]);
    }
    return 0;
}

还有一种dp的方法

dp[n][m]表示 把n拆分成不大于 m的数的方案数

转移的时候按照拆分中的最大的数分类一下。。

dp[n][m]=sum {i=1~n}  ( dp[i][n-i] )----分类中最大数为  1~n

代码写成递归的记忆化搜索了

#include <stdio.h>
#include<string.h>
#include<algorithm>
#include<string>
#include<ctype.h>
using namespace std;
#define MAXN 10000
int dp[130][130];
int dfs(int n,int m)
{
    if(dp[n][m]!=-1)
        return dp[n][m];
    if(m==0)
        return dp[n][0]=0;
    if(n==0)
        return dp[0][m]=1;
    if(m>n)
        return dfs(n,n);
    return dp[n][m]=dfs(n,m-1)+dfs(n-m,m);
}
int main()
{
    memset(dp,-1,sizeof(dp));
    int t,x;
    while(scanf("%d",&x)!=EOF)
    {
        printf("%d\n",dfs(x,x));
    }

    return 0;
}

时间: 2024-10-25 12:52:46

hdu1028:整数拆分的相关文章

[hdu1028]整数拆分,生成函数

题意:给一个正整数n,求n的拆分方法数(不考虑顺序) 思路:不妨考虑用1~n来构成n.用多项式表示单个数所有能构成的数,用多项式表示,就相当于卷积运算了. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 6

整数拆分

将一个整数N拆分成n个连续自然数的和.例如: 15 = 1+2+3+4+5 15 = 4+5+6 15 = 7+8 实现一个函数,打印所有可能,并且统计有多少种方法? 分析过程如下. 对于一个数N, 2个自然数相加:m+(m+1)                                                                                                                  =2m+1 3个自然数相加:(m-1)+m

Pollard-Rho大整数拆分模板

随机拆分,简直机智. 关于过程可以看http://wenku.baidu.com/link?url=JPlP8watmyGVDdjgiLpcytC0lazh4Leg3s53WIx1_Pp_Y6DJTC8QkZZqmiDIxvgFePUzFJ1KF1G5xVVAoUZpxdw9GN-S46eVeiJ6Q-zXdei 看完后,觉得随机生成数然后和n计算gcd,可以将随机的次数根号一下.思想很叼. 对于里面说的birthday trick,在执行次数上我怎么看都只能减一半.只是把平均分布,变成了靠近0

poj 1221 UNIMODAL PALINDROMIC DECOMPOSITIONS 整数拆分

题意: 给一个数n,求有多少种和为n的单峰先增对称序列,比如当n=5时结果为3:(5), (1 3 1), (1 1 1 1 1). 分析: 转化为求类似整数拆分问题,f(i,j)的意义是把i进行拆分,最大数小于等于j的方法数. 代码: //poj 1221 //sep9 #include <iostream> using namespace std; const int maxN=300; __int64 a[maxN+10][maxN+10]; __int64 f(int m,int n)

poj 2229 完全背包变形(求解整数拆分问题)

整数拆分问题:给定一个正整数n,将n拆分为若干数字的和,问有多少种方法? 此题为整数拆分问题的子问题,拆分出的数字要求是2的幂次. 定义dp[i][k]表示枚举到第k个数字时数字i的拆分方案数. 则有状态转移方程: dp[i][k] = dp[i][k - 1] + dp[i - num[k]][k]; 熟悉完全背包的朋友可以看出,这个方程和完全背包的状态转移方程如出一辙,第二维可以省去,只要将i从小到大枚举即可. 1 #include <iostream> 2 #include <cs

poj 3014 Cake Pieces and Plates 整数拆分

题意: 将m拆成n个数,允许某个数为0,求拆分方案数. 分析: 裸的整数拆分,设h(m,n)表示将m拆成n个数,允许某数为0的方案数,递推方程见代码.很有意思的是,参考上一篇写poj1221的博文中,设f(m,n)表示将m进行任意份数不允许有0的整数拆分,且最大元素小于等于m的方案数,则h(m,n)==f(m,n)....求解此等式意义... 代码: //poj 3014 //sep9 #include <iostream> using namespace std; const int max

LightOJ 1336 Sigma Function(数论 整数拆分推论)

--->题意:给一个函数的定义,F(n)代表n的所有约数之和,并且给出了整数拆分公式以及F(n)的计算方法,对于一个给出的N让我们求1 - N之间有多少个数满足F(x)为偶数的情况,输出这个数. --->分析:来考虑F(x)为奇数的情况,给据题目中给我们的公式,,如果F(x)为奇数,那么这个多项式里面的任何一项都必须是奇数,可以知道p = 2时,        p^e - 1肯定是奇数,如果p != 2,当且仅当e为偶数的时候,此项为奇数,证明如下: 原式变形为[ p^(e+1) -p + (

整数拆分问题的四种解法【转载】

http://blog.csdn.net/u011889952/article/details/44813593 整数拆分问题的四种解法 原创 2015年04月01日 21:17:09 标签: 算法 / 母函数定理 / 五边形数定理 / acm / 动态规划 整数划分问题是算法中的一个经典命题之一 所谓整数划分,是指把一个正整数n写成如下形式: n=m1+m2+m3+....+mi;(其中mi为正整数,并且1<=mi<=n),则{m1,m2,m3,....,mi}为n的一个划分. 如果{m1,

【转载转载转载!】整数拆分问题的四种解法--尼奥普兰

整数拆分问题的四种解法 原创 2015年04月01日 21:17:09 标签: 算法 / 母函数定理 / 五边形数定理 / acm / 动态规划 整数划分问题是算法中的一个经典命题之一 所谓整数划分,是指把一个正整数n写成如下形式: n=m1+m2+m3+....+mi;(其中mi为正整数,并且1<=mi<=n),则{m1,m2,m3,....,mi}为n的一个划分. 如果{m1,m2,m3,....,mi}中的最大值不超过m,即max{m1,m2,m3,....,mi} <= m,则称

LeetCode 343.整数拆分 - JavaScript

题目描述:给定一个正整数 n,将其拆分为至少两个正整数的和,并使这些整数的乘积最大化. 返回你可以获得的最大乘积. 题目分析 题目中"n 至少可以拆分为两个正整数的和",这个条件说明了 n 是大于 1 的整数. 对 7 来说,可以拆成 3+4,最大乘积是 12. 对 8 来说,可以拆成 3+3+2,最大乘积是 18. 解法 1: 动态规划 状态数组dp[i]表示:数字 i 拆分为至少两个正整数之和的最大乘积.为了方便计算,dp 的长度是 n + 1,值初始化为 1. 显然dp[2]等于