• 数的计算


    题目描述

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

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

    不作任何处理;

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

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

    输入输出格式

    输入格式:
    11个自然数nn(n le 1000n≤1000)

    输出格式:
    11个整数,表示具有该性质数的个数。

    输入输出样例

    输入样例#1: 复制
    6
    输出样例#1: 复制
    6
    说明

    满足条件的数为

    6,16,26,126,36,136

    思路分析:
    在打代码之前,我们不妨手动模拟一下

    n=0,n=1时,答案显然是1
    n=2, ans=2; n=3,ans=2
    n=4,ans=4; n=5,ans=4
    n=6,ans=6; n=7,ans=6
    相信大家也发现了,2n与2n+1(n为非负整数)的答案是一样的 这就是第一个规律

    然后我们以n=8为例,手动模拟一下

    一共有10组解

    8 1 8 2 8 3 8 4 8

    1 2 8 1 3 8 1 4 8 2 4 8

    1 2 4 8

    我打出的东西很像一棵搜索树。。。

    当我们把8和8下面的左三棵子树放在一起(即8和下面三列),并将所有的8都改成7,我们能发现,我们得到了n=7时的所有解;

    我们再把最右端的子树(即剩下的部分)中的所有8删去,我们得到了n=4时的所有解

    就这样,我们可以得到一个递推式,

    f(n)=f(n-1)                //7=8-1
    
        +f(n/2)                //4=8/2
    

    再结合之前发现的规律

    就能得到:

    n%2==0时
        f(n)=f(n-1)+f(n/2)
    n%2==1时
        f(n)=f(n-1)
    

    然后问题就迎刃而解啦

    参考代码:

    #include <iostream>
    using namespace std;
    int main()
    {
    	int n,cn=1,i,f[1001];
    	f[0]=f[1]=1;
    	cin>>n;
    	for(i=2;i<=n;i++)
    	{
    		if(i%2==0)
    			f[i]=f[i-1]+f[i/2];
    		else
    			f[i]=f[i-1];
    	}
    	cout<<f[n]<<endl;
    	return 0;
    }
    
  • 相关阅读:
    yii2.0 干货
    VLD opcodes 在线查看
    定长顺序串的实现
    循环队列
    oracle--DG初始化参数
    oracle --工具 ODU
    Oracle RAC 修改SPFILE路径 文件查看
    oracle 错误 ORA-00020问题解析
    oracle 错误 TNS-01190与oracle 登入没反应操作
    Oracle--RMAN Recover 缺失的归档操作
  • 原文地址:https://www.cnblogs.com/yonglin1998/p/11780860.html
Copyright © 2020-2023  润新知