码迷,mamicode.com
首页 > 其他好文 > 详细

考研机试 8.整数拆分

时间:2021-02-24 13:24:04      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:tab   int()   通过   practice   动态   表示   过程   情况   void   

 

时间: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();
    }
    
}

 

考研机试 8.整数拆分

标签:tab   int()   通过   practice   动态   表示   过程   情况   void   

原文地址:https://www.cnblogs.com/machi12/p/14439327.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!