zoukankan      html  css  js  c++  java
  • P1028 数的计算

    题目描述

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

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

    1. 不作任何处理;

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

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

    输入格式

    11个自然数nn(n le 1000n1000)

    输出格式

    11个整数,表示具有该性质数的个数。

    输入输出样例

    输入 #1
    6
    
    输出 #1
    6
    

    说明/提示

    满足条件的数为

    6,16,26,126,36,136

    过不了的递归:

    #include<iostream>
    
    using namespace std;
    
    const int N = 2000;
    
    int n = 0;
    int cnt = 1;
    void func(int x){
    	for(int i = 1;i <= x/2;i++){
    		cnt ++;
    		func(i);
    	}
    }
    
    int main(){
    	cin >> n;
    	func(n);
    	cout << cnt;
    
    }
    

      第一种解法:

    f[1]=1
    f[2]=2=f[1]+1
    f[3]=2=f[1]+1
    f[4]=4=f[1]+f[2]+1
    f[5]=4=f[1]+f[2]+1
    
    #include<iostream>
    
    using namespace std;
    const int N = 2000;
    int f[N];
    int main(){
        int n;
        cin >> n;
        for(int i = 1;i <= n;i++){
            for(int j = 1;j <= i/2;j++){
                f[i] += f[j]; 
            }
            f[i]++;
        }
        cout << f[n];
        return 0;
    }
    

      第二种解法:

    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;
    
    const int N = 2000;
    
    int f[N];
    
    int n = 0;
    int cnt = 1;
    
    int main(){
    	cin >> n;
    	f[0] = f[1] = 1;
    	for(int i = 1;i <= n;i++){
    		if(!(i%2)){
    			f[i] = f[i - 1] + f[i/2];
    		}else{
    			f[i] = f[i - 1];  
    		}
    	}
    	cout << f[n];
    	return 0;
    }
    

      第三种:闫式DP

    #include<iostream>
    
    using namespace std;
    
    const int N = 2000;
    
    int f[N];
    
    int n = 0;
    int cnt = 1;
    
    int main(){
    	cin >> n;
    	f[0] = f[1] = 1;
    	for(int i = 1;i <= n;i++){
    		f[i] = f[i - 1];
    		if(!(i%2)){
    			f[i] = f[i - 1] + f[i/2];
    		}
    	}
    	cout << f[n];
    	return 0;
    }
    

      

  • 相关阅读:
    linux下区分各种SCSI磁盘类型
    Linux那些事儿之我是SCSI硬盘(3)磁盘磁盘你动起来!
    待机(STR)suspend device flow
    %pf
    ftrace misc
    reboot系统调用的时候会调用shutdown函数
    Linux进程调度
    一张图让你读懂Linux内核运行原理
    linux O1 and CFS process sched
    SQL 视图 触发器 等
  • 原文地址:https://www.cnblogs.com/luyuan-chen/p/11681898.html
Copyright © 2011-2022 走看看