zoukankan      html  css  js  c++  java
  • (数论)数的计算

    题目描述 Description

    我们要求找出具有下列性质数的个数(包含输入的自然数n):

    先输入一个自然数n(n<=1000),然后对此自然数按照如下方法进行处理:

    1.          不作任何处理;

    2.          在它的左边加上一个自然数,但该自然数不能超过原数的一半;

    3.          加上数后,继续按此规则进行处理,直到不能再加自然数为止.

    输入描述 Input Description

    一个数n

    输出描述 Output Description

    满足条件的数的个数

    样例输入 Sample Input

    6

    样例输出 Sample Output

    6

    数据范围及提示 Data Size & Hint

    6个数分别是:

    6

    16

    26

    126

    36

    136

    分析:

        1. 本题难度看似不大,但如果用递归来做的话耗时非常大,因为需要重复计算的数据量太大了。当然我们也可以采取一边递归一边储存的方法,但计算量也还是不小,再进一步思考,实际上就是可以用如下的递推法来做;
        2. 例如要求f(6),经过分析,我们知道:f(6)=f(1)+f(2)+f(3)+1,也就是说,f(6)的答案数量是在它之前可以取的所有自然数的答案数量之和(6之前可以取1,2,3三个自然数),最后加1是指数字6本身也是一个答案;
        3. 所以,我们可以知道f(n)=f(1)+f(2)+......f(trunc(n/2))+1;
        4. 因此,要求f(n),我们只需用上述公式编一个递推过程,把f(2)到f(n)全部求出即可,对于f(1000)也不超过1秒就能得到结果。
        第二种算法:
        1. 对于f(7)=f(6)是显而易见的,也即f(2n+1)=f(2n)。那么,f(8)和f(7)之间有什么关系呢?
        2. 分析可知:f(8)和f(7)的差别是,f(8)除了包含f(7)的所有情况外,还要多加上f(4),即:f(8)=f(7)+f(4)。因此可得:f(2n)=f(2n-1)+f(n)。只需据此编一个递归小过程或者用递推方法即可。

     1 #include <iostream>
     2 using namespace std;
     3 int main()
     4 {
     5     int i,n,ans,sum[1001];
     6     sum[0] = 0,sum [1] = 1;
     7     cin>>n;
     8     for(i = 2 ; i <= n ; i++)
     9     {
    10         ans = sum[i/2] + 1;
    11         sum [i] = sum[i-1] + ans;
    12     }
    13     cout<<sum[n] - sum[n-1]<<endl;
    14     return 0;
    15 }
    View Code
    随便写写。一点学习心得。。。--如果本文章没有注明转载则为原创文章,可以随意复制发表,但请注明出处与作者
  • 相关阅读:
    git系列3之简单命令(查看不同|文件提交|文件移除|重命名)
    git系列2之简单命令(乱码问题|修改文件提交|忽略文件)
    git系列1之安装初体验(windows)
    mongodb主从复制副本集(12)
    mongodb系统知识(11)
    mongodb系统知识(10)
    linux下h2集群创建,及java集成详细步骤
    windows下创建h2集群,及java集成详细步骤
    MySQL与Oracle 差异比较之一数据类型
    快速恢复update了的orcale数据表
  • 原文地址:https://www.cnblogs.com/ganhang-acm/p/4167513.html
Copyright © 2011-2022 走看看