zoukankan      html  css  js  c++  java
  • 究极无敌卧槽2的幂数

    文章出处:http://www.cnblogs.com/skyiv/archive/2010/03/27/1698550.html

    数的分解,据说是清华的一道复试上机题

    来源: http://topic.csdn.net/u/20100325/20/38e39935-9463-452c-a194-1ed8f6b49c99.html

    任何数都能分解成2的幂,
    例如:7
    =1+1+1+1+1+1+1
    =1+1+1+1+1+2
    =1+1+1+2+2
    =1+1+1+4
    =1+2+2+2
    =1+2+4
    求任意整数n(n<100亿)的此类划分数。


    解:

    记f(n)为n的划分数,我们有递推公式:
    f(2m + 1) = f(2m),
    f(2m) = f(2m - 1) + f(m),
    初始条件:f(1) = 1。


    证明:

    证明的要点是考虑划分中是否有1。

    记:
    A(n) = n的所有划分组成的集合,
    B(n) = n的所有含有1的划分组成的集合,
    C(n) = n的所有不含1的划分组成的集合,
    则有: A(n) = B(n)∪C(n)。

    又记:
    f(n) = A(n)中元素的个数,
    g(n) = B(n)中元素的个数,
    h(n) = C(n)中元素的个数,
    易知: f(n) = g(n) + h(n)。

    以上记号的具体例子见文末。


    我们先来证明: f(2m + 1) = f(2m),
    首先,2m + 1 的每个划分中至少有一个1,去掉这个1,就得到 2m 的一个划分,故 f(2m + 1)≤f(2m)。
    其次,2m 的每个划分加上个1,就构成了 2m + 1 的一个划分,故 f(2m)≤f(2m + 1)。
    综上,f(2m + 1) = f(2m)。

    接着我们要证明: f(2m) = f(2m - 1) + f(m),
    把 B(2m) 中的划分中的1去掉一个,就得到 A(2m - 1) 中的一个划分,故 g(2m)≤f(2m - 1)。
    把 A(2m - 1) 中的划分加上一个1,就得到 B(2m) 中的一个划分,故 f(2m - 1)≤g(2m)。
    综上,g(2m) = f(2m - 1)。

    把 C(2m) 中的划分的元素都除以2,就得到 A(m) 中的一个划分,故 h(2m)≤f(m)。
    把 A(m) 中的划分的元素都乘2,就得到 C(2m) 中的一个划分,故 f(m)≤h(2m)。
    综上,h(2m) = f(m)。

    所以: f(2m) = g(2m) + h(2m) = f(2m - 1) + f(m)。                                            

    这就证明了我们的递推公式。


    记 f(0) = 1,根据递推公式,可以得到:
    f(2m) = f(0) + f(1) + ... + f(m)。
    (证明留给读者)


    一些例子:

    A(3) = {
      (1,1,1)
      (1,2)
    },
    f(3) = 2,

    A(4) = {
     (1,1,1,1)
      (1,1,2)
      (2,2)
      (4)
    },
    f(4) = 4,

    A(5) = {
     (1,1,1,1,1)
      (1,1,1,2)
      (1,2,2)
      (1,4)
    },
    f(5) = 4,

    A(6) = {
     (1,1,1,1,1,1)
      (1,1,1,1,2)
      (1,1,2,2)
      (1,1,4)
      (2,2,2)
      (2,4)
    },
    f(6) = 6,

    B(6) = {
     (1,1,1,1,1,1)
      (1,1,1,1,2)
      (1,1,2,2)
      (1,1,4)
    },
    g(6) = 4,

    C(6) = {
      (2,2,2)
      (2,4)
    },
    h(6) = 2.

    结合今天的这道题:

    题目描述

    小明开始学习二进制转化到十进制,其中要用到2的幂(2的3次幂就是3个2相乘),他觉得这个很有意思。既然通过2的幂相加可以得到十位数,那么反过来,一个十进制数是否可以通过若干个2的幂相加得到呢?
    小明开始研究起来,他先列出了所有2的幂:1,2,4,8,16,32,64……。
    4=1+1+1+1
    4=1+1+2
    4=2+2
    4=4                 4共有4种方法
    7=1+1+1+1+1+1+1
    7=1+1+1+1+1+2
    7= 1+1+1+2+2
    7=1+1+1+4
    7=1+2+2+2
    7= 1+2+4       
    共有6种方法。1+2+4和2+1+4认为是同一个等式,因为它们的组成相同。
    现在小明想要知道,给出一个十进制数,可以写出多少种,用若干个2的幂数相加的式子。

    输入

    第一行包含1个正整数n, 1<=n<=1000。

    输出

    共1行,n能用2的幂数相加的不同式子的种数。

    样例输入

    复制样例数据

    7
    

    样例输出

    6
    #include <iostream>
    
    using namespace std;
    int fun(int n){
        if(n==1||n==2) return n;
        else if(n%2==0) return fun(n/2)+fun(n-1);
        else return fun(n-1);
    }
    int main()
    {
        int n;
        cin>>n;
        cout<<fun(n)<<endl;
        return 0;
    }
    

    我没找出这个规律

  • 相关阅读:
    100%解决XP系统asp http500内部错误[转自XX博客]
    .net使用DotNetCharting控件生成报表统计图总结 (转地址)
    关于request取中文字符串变?的解决办法
    Delete删除大批量数据无响应的解决办法
    点击GridView模版列里的按钮取GridView当前被操作行的数据(转载)
    繁體字顯示問題
    寫博客過程中遇到的問題
    box model相關的API
    Buddhism常用術語
    靡不有初鮮克有終
  • 原文地址:https://www.cnblogs.com/skyleafcoder/p/12319559.html
Copyright © 2011-2022 走看看