zoukankan      html  css  js  c++  java
  • 牛客网计算机考研复试-KY8-整数拆分

    题目链接:点这里


    题目描述:
    一个整数总可以拆分为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。


    思路:
    使用动态规划的思想,最终得到代码中的两个式子,

    f(2m+1) = f(2m)
    f(2m) = f(2m-1)+f(m)

    具体的思路,搬运一下评论里的(原文在题目链接评论中,举的例子比较好理解):

    思路:通过递推公式,划分为子问题求解。
    问题:一个整数拆分为2的幂的和。即(1, 2, 2^2, 2^3,..., 2^k),包含1个奇数和k个偶数。
    对于N,分为两种情况:
    1)N为奇数(2m+1),则每个拆分结果必然至少有一个1,因为只通过k个偶数无法组成奇数。所以f(2m+1) = f(2m)
    例如 f(5) 1+(4) 1+(2+2) 1+(1+1+2) 1+(1+1+1+1+1)
    f(4) 4 2+2 1+1+2 1+1+1+1+1
    2) N为偶数(2m),拆分同样分为两类:拆分结果中包含1和拆分结果不包含1
    a) 拆分结果包含1 (奇拆分):所有的拆分数目为f(2m-1),同上
    b) 拆分结果不包含1(偶拆分):拆分数目为f(m)。 拆分结果不包含1,说明是拆分成了k个偶数,那么对每一种拆分结果都除以2,并不会影响整体拆分的数目。但是每个拆分结果的sum都变成了m,即每个2m的偶拆分都变成了m的拆分。同样对m的每种拆分结果都乘以2,拆分结果的sum都变成了2m且不包含1。即m的拆分和2m的偶拆分一一对应。
    例如f(8) (不包含1的拆分有四种) 8 4+4 2+2+4 2+2+2+2
    f(4)(所有拆分有四种) 4 2+2 1+1+2 1+1+1+1
    f(2m) = f(2m-1) + f(m)

    综上所述:
    f(2m+1) = f(2m)
    f(2m) = f(2m-1) + f(m)


    代码:

    #include <bits/stdc++.h>
    using namespace std;
    const int mod = 1e9;
    const int maxn = 1e6+2;
    int f[maxn];
    int main(){
        int n;
        f[1] = 1;
        for(int i=2;i<=1e6;i++){
            if(i%2==1)
                f[i] = f[i-1];
            else
                f[i] = (f[i-1]+f[i/2])%mod;
        }
        while(cin >> n){
            cout << f[n] << endl;
        }
        return 0;
    }
    
    
  • 相关阅读:
    /proc/uptime详解
    UE没法远程修改文件
    ssh隐藏的sftp功能的使用
    ftp配置文件
    如何判断网线是否连接
    NTP多种模式的配置
    系统开机启动过程
    window BIOS设置硬盘启动模式
    shell加密
    /etc/sysconfig/network-scripts/下文件介绍
  • 原文地址:https://www.cnblogs.com/123-wind/p/14296766.html
Copyright © 2011-2022 走看看