清华考研复试上机——整数拆分

本文介绍了一种利用动态规划解决整数拆分问题的方法,即求一个整数能被拆分成2的幂之和的不同方式的数量。通过将问题转换为完全背包问题的形式,并给出具体的实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一个整数总可以拆分为2的幂的和,例如: 7=1+2+4 7=1+2+2+2 7=1+1+1+4 7=1+1+1+2+27=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

    思路:刚遇到这道题的时候手足无措,背别人一点拨,原来这是一个完全背包的问题,只是换了个皮。背包问题是动态规划的经典问题了。

    完全背包就是说有若干个物品,每个物品都可以重复使用无数次,一个容量为N的背包要恰好放入这若干个物品。这道题是问有多少种放法,物品是1,2,4,8, ... 2^p,显然只需要算到2^p <= N的最大的p既可。

    因为题目明确给出了数据范围,因此先算出来上面p个数字,然后算出从1~N的所有结果,测试时只需要查表既可。

#include <cstdio>
#include <cstdlib>
#include <climits>
#include <memory>
#include <cstring>
#include <cmath>
#include <map>
#include <iostream>
using namespace std;

const int MAXN = 1000005;

int stuff[100];
int stuffCount;

int dp[MAXN];

int main()
{
    stuffCount = 0;
    for(int i=1; i < MAXN; i *= 2)
    {
        stuff[stuffCount++] = i;
    }

    dp[0] = 1;
    for(int i=0; i < stuffCount; i++)
    {
        for(int j=stuff[i]; j < MAXN; j++)
        {
            dp[j] = (dp[j]%1000000000 + dp[j-stuff[i]]%1000000000)%1000000000;
        }
    }
    int n;
    while(cin>>n)
    {
        cout << dp[n] << "\n";
    }
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值