牛客网 整数拆分(完全背包、清华机试)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sunlanchang/article/details/88067902

题目描述

一个整数总可以拆分为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

Solution

完全背包的变形。

#include <iostream>
#include <cstring>
#include <cstdio>
//看做至多30个物品,每个物品可重复使用,组成和为k的方案有多少种?完全背包问题
using namespace std;
const int mod = 1000000000; //模必须这么大,不能增大
const int maxn = 1000011;
int bit[30]; //30个物品weight分别是1、2、8、16。。。。
int dp[maxn];
int main()
{
    memset(dp, 0, sizeof(dp));
    //初始化物品的weight
    bit[0] = 1; //2的0次方等于1
    for (int i = 1; i <= 30; i++)
        bit[i] = bit[i - 1] * 2;
    dp[0] = 1;                    //0只有一种拆解方法
    for (int i = 0; i <= 30; i++) //遍历30种物品weight
    {
        for (int j = bit[i]; j <= maxn; j++) //遍历背包的容量
        {
            dp[j] += dp[j - bit[i]]; //状态转移
            dp[j] %= mod;
        }
    }
    int n;
    while (~scanf("%d", &n))
        printf("%d\n", dp[n]);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/sunlanchang/article/details/88067902