博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
(数论)数的计算
阅读量:5277 次
发布时间:2019-06-14

本文共 1176 字,大约阅读时间需要 3 分钟。

题目描述 
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 
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<
View Code

 

转载于:https://www.cnblogs.com/ganhang-acm/p/4167513.html

你可能感兴趣的文章
软件测试工作量的评估清单
查看>>
Object C学习笔记8-字符串NSString之二
查看>>
算法笔记 3.2 codeup1935 查找学生信息
查看>>
DataTable转List,转对象
查看>>
1185: 零起点学算法92——单词数
查看>>
IOS HTML点击时有背景阴影
查看>>
svn登录问题
查看>>
[Java复习01] Java基础 Basic
查看>>
使用scipy.genfromtxt()报错
查看>>
java-接口—策略模式
查看>>
[AHOI2006]文本编辑器 Splay tree区间操作
查看>>
android自定义动画
查看>>
ANR和FC
查看>>
bzoj 2823: [AHOI2012]信号塔 最小圆覆盖
查看>>
CLRS最大子数组问题
查看>>
[Android 步步为营]第2营:Hello World 第一个Android应用(下)
查看>>
【转】ssh登录慢,等待输入密码时间长的解决办法
查看>>
冒泡选择插入三种排序
查看>>
外键建立失败
查看>>
font-face
查看>>