整数拆分

1.整数二次幂拆分

1.1题目描述:

题目描述
一个整数总可以拆分为2的幂的和,例如: 7=1+2+4 7=1+2+2+2 7=1+1+1+4 7=1+1+1+2+2 7=1+1+1+1+1+2 7=1+1+1+1+1+1+1 总共有六种不同的拆分方式。 再比如:4可以拆分成:4 = 4,4 = 1 + 1 + 1 + 1,4 = 2 + 2,4=1+1+2。 用f(n)表示n的不同拆分的种数,例如f(7)=6. 要求编写程序,读入n(不超过1000000),输出f(n)%1000000000。
输入描述:
每组输入包括一个整数:N(1<=N<=1000000)。
输出描述:
对于每组数据,输出f(n)%1000000000。
示例1
输入
7
输出
6

1.2.基本思路

定义规划数组dp[N],其中dp[i]=f(i),可以等到如下递推方程:

①当i为奇数的时候,dp[i]只需在dp[i-1]的所有情况上加上1即可
②当i为偶数的时候,dp[i]有两部分组成,
—1>拆分后的整数中包含1, d p [ i − 1 ] dp[i-1] dp[i1]
—2>拆分后的整数中不包含1, d p [ i 2 ] dp[\frac{i}{2}] dp[2i]

1.3.代码实现

/**
采用动态规划的方法求解,分两种情况考虑
①当i为奇数的时候
  dp[i]=dp[i-1]
②当i为偶数的时候
  dp[i]=dp[i-1]+dp[i/2]
  其中dp[i-1]表示拆解的整数中含有1的情况
  dp[i/2]表示拆解的整数中不含有1的情况
*/
#include <iostream>
#define N 1000001
using namespace std;
int buf[N];
int main()
{
    int n;
    while(cin>>n){
        for(int i=1;i<=n;i++){
            if(i==1)
                buf[i]=1;
            else if(i%2!=0)
                buf[i]=buf[i-1];
            else
                buf[i]=(buf[i-1]+buf[i/2])%1000000000;
        }
        cout<<buf[n]<<endl;
    }
    return 0;
}

2.整数拆分

2.1题目描述:

将给定正整数n表示成一些列整数的之和, n = n 1 + n 2 + . . . + n k n=n_1+n_2+...+n_k n=n1+n2+...+nk,其中n_1≥n_2≥…≥n_k≥1,k≥1.求正整数n的不同划分个数p(n)
例如:
6;
5+1;
4+2, 4+1+1;
3+3, 3+2+1, 3+1+1+1;
2+2+2, 2+2+1+1, 2+1+1+1+1;
1+1+1+1+1+1;

2.2.基本思路

该问题具有比较明显的递归关系,因而容易采用递归的函数进行求解。而在该问题中递归的关系不太明显,p(n)为整数n的划分数,则比较难以找到递归的关系,因此需要增加一个自变量:将最大数n不大于m的划分个数记为q(n,m).可以建立如下递推关系式:
在这里插入图片描述
对于n>m>1这种情况比较难于理解:
分为以下两种情况:
在这里插入图片描述
所以n>m>1的时候得到公式: q ( n , m ) = q ( n , m − 1 ) + q ( n − m , m ) q(n,m)=q(n,m-1)+q(n-m,m) q(n,m)=q(n,m1)+q(nm,m)

2.3.代码实现

#include <iostream>

using namespace std;

int q(int n,int m){
    if(n==1&&m==1)
        return 1;
    else if(m>n){
        return q(n,n);
    }
    else if(m==n){
        return 1+q(n,n-1);
    }
    else if(m>=1&&m<n){//
        return q(n,m-1)+q(n-m,m);
    }
    else{
        return 0;
    }
}

int main()
{
    int n;
    while(cin>>n){
        cout<<q(n,n)<<endl;
    }
    return 0;
}

参考博客:https://blog.csdn.net/u011889952/article/details/44813593

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值