zoukankan      html  css  js  c++  java
  • 考研机试 8.整数拆分

    时间:2021/02/24

    一.题目描述

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

     题目链接

    https://www.nowcoder.com/practice/376537f4609a49d296901db5139639ec?

    tpId=40&tqId=21339&rp=1&ru=%2Fta%2Fkaoyan&qru=%2Fta%2Fkaoyan%2Fquestion-ranking&tab=answerKey

    二.算法

    题解

    这是一个动态规划问题,重点是要找到递推式,一般不要用递归求解问题,因为可能会超时,可以通过辅助数组将递归(从上到下)转化为循环(从下到上)的形式。

    递推式如下:如果n为奇数,则f(n) = f(n-1);如果n为偶数,则f(n) = f(n-1) + f(n/2)。

    下面是一个大佬对递推式的分析过程:(主要通过划分奇拆分和偶拆分来求解)

    思路:通过递推公式,划分为子问题求解。
    问题:一个整数拆分为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)

    重点

    动态规划

    代码

    import java.util.Scanner;
    
    public class Main{
        
        public static void main(String[] args){
            
            Scanner in = new Scanner(System.in);
            int max = 1000001;
            int[] count = new int[max];
            count[1] = 1;
            count[2] = 2;
            
            for(int i = 3; i < max; i++){
                
                if(i % 2 == 1){
                        count[i] = (count[i - 1] % 1000000000);
                    }
                    else{
                        count[i] = ((count[i - 1] + count[i / 2]) % 1000000000);
                    }
            }
            
            while(in.hasNext()){
                int n = in.nextInt();
                
                System.out.println(count[n]);
            }
            
            in.close();
        }
        
    }
  • 相关阅读:
    第72天: PySpider框架的使用
    第71天: Python Scrapy 项目实战
    Web前端资源汇总
    1201即将到来
    C#自定义事件模拟风吹草摇摆
    HTML5 Canvas爱心时钟代码
    CSS3圆环动态弹出菜单
    CSS3实现Loading动画特效
    HTML5优势
    CSS3扁平化Loading动画特效
  • 原文地址:https://www.cnblogs.com/machi12/p/14439327.html
Copyright © 2011-2022 走看看