• 【九度OJ】题目1084:整数拆分


    原题:

    题目描述: 
    一个整数总可以拆分为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 = 44 = 1 + 1 + 1 + 14 = 2 + 24=1+1+2。
    用f(n)表示n的不同拆分的种数,例如f(7)=6.
    要求编写程序,读入n(不超过1000000),输出f(n)%1000000000。
    
    输入: 
    每组输入包括一个整数:N(1<=N<=1000000)。
    
    输出: 
    对于每组数据,输出f(n)%1000000000。
    
    样例输入: 
    7样例输出: 
    6

    解题思路: 参考:http://www.cnblogs.com/love533/archive/2012/03/29/2423119.html

    对于奇数n=2k+1:它的拆分的第一项一定是1,考虑去掉这个1,其实就一一对应于
    2k的拆分,因此f(2k+1)=f(2k).

    对于偶数n=2k:考虑有1和没有1的拆分。有1的拆分,与(2k-1)的拆分一一对应,与上面奇数的情况
    理由相同;没有1的拆分,将每项除以2,正好一一对应于k的所有拆分。因此f(2k)=f(2k-1)+f(k).

    需要注意f(n)会很大,不要溢出了。最终结果只要求除以十亿的余数,在int的表示范围内,
    因此不需要大数运算。注意余数的性质:(a+b)%m == (a%m+b%m)%m,所以只要对每个中间
    结果也都取余数,就不会有溢出的问题,且不改变最终输出结果。

    解题代码:

    C语言代码:

    #include <stdio.h>
    #include <stdlib.h>
    
    int f[1000001];//增加一个
    
    int main()
    {
        int n;
        while(scanf("%d",&n)!=EOF)
        {
            printf("%d\n",fun(n));
        }
        return 0;
    }
    
    int fun(int n)  //求解并返回 f(n)
    {
        f[1] = 1;
        f[2] = 2;
        int i;
        for(i=3; i<=n; i++)
        {
            if (i % 2) //i能被2整除的话余数是0,反之不为0,即为真
            {
                f[i] = f[i-1];
            }
            else
            {
                f[i] = (f[i/2] + f[i-1])%1000000000;
            }
        }
        return f[n];
    }
  • 相关阅读:
    [NOIP2017 TG D2T2]宝藏(模拟退火)
    [洛谷P1337][JSOI2004]平衡点 / 吊打XXX
    [洛谷P4940]Portal2
    [CF1073E]Segment Sum
    [CF1066C]Books Queries
    [CF1065C]Make It Equal
    [洛谷P3469][POI2008]BLO-Blockade
    网络模型 ------->MobileNet-v3
    C++--------------------->>>>>>cmakelist的编写
    C++ ----------------》》》》》cmake list的
  • 原文地址:https://www.cnblogs.com/yinger/p/2644312.html
Copyright © 2020-2023  润新知