1316:【例4.6】数的计数(Noip2001) 代码+解析

1316:【例4.6】数的计数(Noip2001)

【题目描述】

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

)。先输入一个自然数n(n≤1000),然后对此自然数按照如下方法进行处理:不作任何处理;在它的左边加上一个自然数,但该自然数不能超过原数的一半;加上数后,继续按此规则进行处理,直到不能再加自然数为止。

【输入】

自然数n(n≤1000)。

【输出】

满足条件的数。

【输入样例】

6

【输出样例】

6

【提示】

【样例解释】

满足条件的数为如下所示:

6

16

26

126

36

136

思路:

  • 首先分析: 一个自然数左边加上一个自然数:举例-100,左边加上后可以为50100,,,,2550,,,,,49100,,,24100,,,所以他的数量为1~50这五十个自然数的每次计数之和
  • 由于每个自然数独一无二,左边加上一个自然数就多了该自然数的排列方式,所以可以理解为前n/2个自然数不同排列组成的数的个数之和
  • 由于数据庞大,在使用递归式时可以考虑该数组的值是否已经求了,如果已求,则可以直接跳过,节省运行时间(记忆搜索
  • 如果采用一层for循环的递归方式则会超时:用一个变量去存,由于每次都要从1开始计算,所以会超时
cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
//由于直接每次num(i),只是用sum记忆次数,则会超时,所以选择用记忆的方式,每次计算后存起来 
//记忆搜索(一个if判断数组值是否为0)+递归 
int sum = 0,a[1001];
//定义计数的函数
void num(int m) ;
int main(){
	int n;
    cin>>n;
	num(n);
	cout<<a[n];
	return 0;
} 
void num(int m){
    
    if(a[m]>0) return;//表示该数值已经求到了
    a[m]=1;// 自身也是一种情况 
	for(int i=1;i<=m/2;i++){
		num(i);//每次都递归一下(避免前面的数未计数) 
		a[m]+=a[i];
	}
}
相关推荐
qq_454245038 分钟前
BuildTemplateGraph 函数深度解析:动态节点图构建的架构设计与核心价值
数据结构·c#
liulun12 分钟前
C++ WinRT中的异步
c++·windows
xsyaaaan14 分钟前
代码随想录Day39动态规划:115不同的子序列_583两个字符串的删除操作_72编辑距离_编辑距离总结
算法·动态规划
陈天伟教授15 分钟前
人工智能应用- 人工智能交叉:05. 从 AlphaFold1 到 AlphaFold2
人工智能·神经网络·算法·机器学习·推荐算法
Eloudy42 分钟前
直接法 读书笔记 05 第5章 正交方法
人工智能·算法·机器学习
iAkuya1 小时前
(leetcode)力扣100 73柱状图中最大的矩形(单调栈)
算法·leetcode·职场和发展
qq_454245031 小时前
SkeletonFlow:基于组合子逻辑与范畴论的数据流处理框架
数据结构·c#
王老师青少年编程1 小时前
2020年信奥赛C++提高组csp-s初赛真题及答案解析(阅读程序第1题)
c++·题解·真题·初赛·信奥赛·csp-s·提高组
pp起床1 小时前
动态规划 | part03
算法·动态规划
会周易的程序员1 小时前
cNetgate插件架构设计详解 动态库 脚本二开lua, python, javascript
javascript·c++·python·物联网·lua·iot