LFYZ-OJ ID: 1026 数的计数(数的计算)NOIP2001
数的计算(数的计数)
题目描述
我们要求找出具有下列性质数的个数(包含输入的自然数n)。先输入一个自然数n(n<=1000),然后对此自然数按照如下方法进行处理:
- 不作任何处理;
- 在它的左边加上一个自然数,但该自然数不能超过原数的一半;
- 加上数后,在新加上数的左边继续按此规则进行处理,直到不能再加自然数为止.
例如:
输入: 6
满足条件的数为 6 (此部分不必输出)
16
26
126
36
136
输出: 6
输入
只有一行一个整数,为自然数n(n<=1000)
输出
输出满足条件数的个数
样例输入
6
样例输出
6
分析
手动按照上述过程进行计算,会发现这是个递归的过程,对每一个原始数字m,在前面加i(1,2,3,...m/2),即
h(n)=1+h(1)+f(2)+...+h(n/2)
,对于每一个i,要按照同样的规则进行,这用递归可以实现(见例程1),递归过程中,每遇到一个原始数,计数器加1,用来统计个数。例程1在OJ中会显示超时,这是必然的,当n很大时,递归的过程就会很长,这主要源于其中会做大量的重复计算,每次计算h(n),都要重复计算h(1)....h(n/2),这样的问题在使用递归计算斐波那契数f(n)时,也会遇到,程序效率很低。解决的一个途径是使程序具有记忆功能,已计算出的数字就无需再次计算,直接使用即可。例程2使用数组实现了带记忆功能的递归,可以通过OJ系统。
也可以使用递推的方法来解决问题:已知
h(n)=1+h(1)+h(2)+...+h(n/2)
,这就是一个递归式,程序写起来很容易(见例程3),两层for循环就可完成,递推比起无记忆的递归来效率要高得多。例程1是指数级的时间复杂度,而例程3的时间复杂度为O(n2)。问题可以进一步简化。通过对上面的公式进行推导可以发现:n为奇数时,
h(n)=h(n-1)
,n为偶数时,h(n)=h(n-1)+h(n/2)
,看懂了吗,使用这两个公式,可以将时间复杂度降低到O(n),见例程4。
例程1
#include<iostream>
using namespace std;
int ans; //计数器
void dfs(int m){
ans++; //每出现一次原始数,ans++
for(int i=1; i<=m/2; i++){
dfs(i); //递归
}
}
int main(){
int n;
cin>>n;
dfs(n);
cout<<ans;
return 0;
}
例程2
#include<iostream>
using namespace std;
int h[1001]; //记忆数组,存储计算出的h[m]
void dfs(int m){
if(h[m]!=0) return; //有记忆,不再递归
h[m]=1; //无记忆,初始化为1,递归累加计算
for(int i=1; i<=m/2; i++){
dfs(i); //递归
h[m]+=h[i]; //累加
}
}
int main(){
int n;
cin>>n;
dfs(n);
cout<<h[n];
return 0;
}
例程3
#include<iostream>
using namespace std;
int h[1001];
int main(){
int n;
cin>>n;
h[1]=1; //初始化第一项h[1]
for(int s=2;s<=n;s++){ //对第s项
h[s]=1; //数字s自己算一个
for(int i=1;i<=s/2;i++) h[s]+=h[i];
}
cout<<h[n];
return 0;
}
例程4
#include<iostream>
using namespace std;
int main(){
int n;
cin>>n;
h[1]=1; //初始化第一项
for(int i=2; i<=n; i++){
h[i]=h[i-1]; //递推
if(i%2==0) h[i]+=h[i/2]; //i为偶数时
}
cout<<h[n];
return 0;
}
LFYZ-OJ ID: 1026 数的计数(数的计算)NOIP2001的更多相关文章
- ACM——数的计数
http://acm.njupt.edu.cn/acmhome/problemdetail.do?&method=showdetail&id=1050 数的计数 时间限制(普通/Jav ...
- 【BZOJ 1026】 [SCOI2009]windy数
[题目链接]:http://www.lydsy.com/JudgeOnline/problem.php?id=1026 [题意] [题解] 数位Dp 设f[i][j]表示长度为i,第一位(也就是最高位 ...
- 数的计数(number)
数的计数(number) 题目描述 我们要求找出具有下列性质数的个数(包含输入的自然数n),先输入一个自然数n(n≤1000),然后对此自然数按照如下方法进行处理: (1)不作任何处理: (2)在它的 ...
- 九度OJ 1060:完数VS盈数 (数字特性)
时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:5590 解决:2093 题目描述: 一个数如果恰好等于它的各因子(该数本身除外)子和,如:6=3+2+1.则称其为"完数" ...
- 九度oj 题目1060:完数VS盈数
题目1060:完数VS盈数 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:6461 解决:2426 题目描述: 一个数如果恰好等于它的各因子(该数本身除外)子和,如:6=3+2+1.则称其 ...
- 【集训笔记】【大数模板】特殊的数 【Catalan数】【HDOJ1133【HDOJ1134【HDOJ1130
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3324 http://blog.csdn.net/xymscau/artic ...
- hive优化之——控制hive任务中的map数和reduce数
一. 控制hive任务中的map数: 1. 通常情况下,作业会通过input的目录产生一个或者多个map任务.主要的决定因素有: input的文件总个数,input的文件大小,集群设置的文 ...
- centos系统查看系统版本、内核版本、系统位数、cpu个数、核心数、线程数
centos查看系统版本 cat /etc/redhat-release CentOS Linux release 7.2.1511 (Core) 1)查看centos内核的版本: [root@loc ...
- Android 简单统计文本文件字符数、单词数、行数Demo
做的demo是统计文本文件的字符数.单词数.行数的,首先呢,我们必须要有一个文本文件.所以我们要么创建一个文本文件,并保存,然后再解析:要么就提前把文本文件先放到模拟器上,然后检索到文本名再进行解析. ...
随机推荐
- 什么是POE交换机?
POE交换机和普通交换机的区别有: 1.POE交换机不但可以实现普通交换机的数据传输功能还能同时对网络终端进行供电 .普通的交换机主要是交换数据的功能,并没有具备供电的功能. 2.现在的网络高清摄像机 ...
- A Deep Learning-Based System for Vulnerability Detection
本篇文献作者提出了一种基于深度学习来检测软件漏洞的方案. 摘要:作者开始基于深度学习的漏洞检测研究,是为了减轻专家手工定义特性的繁琐任务,需要制定一些指导性原则来适用于深度学习去进行漏洞探 ...
- 3星|《给产品经理讲技术》:APP开发技术介绍,没有技术背景的话恐怕只能看懂书中的比喻和结论
基本是APP开发涉及到的相关技术的入门级介绍.涉及到的知识点与技术细节比较多,不少技术相关的内容并没有像标题暗示的那样没有技术背景也可以看懂,而是涉及到许多专业的术语.原理.也有一些内容是用比喻的方法 ...
- Python开发【前端篇】HTML
1.html概述和基本结构 html概述 HTML是 HyperText Mark-up Language 的首字母简写,意思是超文本标记语言,超文本指的是超链接,标记指的是标签,是一种用来制作网页的 ...
- 构建高性能服务 Java高性能缓冲设计 vs Disruptor vs LinkedBlockingQueue
一个仅仅部署在4台服务器上的服务,每秒向Database写入数据超过100万行数据,每分钟产生超过1G的数据.而每台服务器(8核12G)上CPU占用不到100%,load不超过5.这是怎么做到呢?下面 ...
- UVA10054-The Necklace(无向图欧拉回路——套圈算法)
Problem UVA10054-The Necklace Time Limit: 3000 mSec Problem Description Input The input contains T t ...
- SpringCloud搭建Eureka集群
第一部分:搭建Eureka Server集群 Step1:新建工程,引入依赖 依赖文件pom.xml如下 <?xml version="1.0" encoding=" ...
- webpack4配置详解之新手上路初探
前言 经常会有群友问起webpack.react.redux.甚至create-react-app配置等等方面的问题,有些是我也不懂的,慢慢从大家的相互交流中,也学到了不少. 今天就尝试着一起来聊 ...
- 循环语句之for循环
什么是循环语句? 循环语句可以在满足循环条件的情况下,反复执行某一段代码,这段被重复执行的代码被称为循环体语句,当反复执行这个循环体时,需要在合适的时候把循环判断条件修改为false,从而结束循环,否 ...
- 动态链接库-Win32 DLL的说明
在实际编程时,我们可以把完成某种功能的函数放在一个动态链接库中,然后给其他程序调用. WinAPI中所有的函数都包含在3个最重要的DLL中. Kernel32.dll 它包含那些用于管理内存.进程和线 ...