1316:【例4.6】数的计数(Noip2001) 代码+解析
2023-12-21 19:02:47
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开始计算,所以会超时
#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];
}
}
文章来源:https://blog.csdn.net/m0_46183615/article/details/135137283
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!