1914:【01NOIP普及组】数的计数
时间限制: 1000 ms 内存限制: 65536 KB
提交数: 8148 通过数: 4213
【题目描述】
我们要求找出具有下列性质数的个数(包含输入的自然数nn):
先输入一个自然数n(n≤1000)n(n≤1000),然后对此自然数按照如下方法进行处理:
1.不作任何处理;
2.在它的左边加上一个自然数,但该自然数不能超过原数的一半;
3.加上数后,继续按此规则进行处理,直到不能再加自然数为止。
【输入】
输入nn。
【输出】
数的个数
【输入样例】
6
【输出样例】
6
【提示】
样例说明:
这6个数是:
6
16
26
126
36
136
思路:
这道题是动态规划
f[i]代表数字 i 的个数
只细观察,我们能发现什么?
26 126
这是6的两个数,我们发现,6左边加上的数其实就是加上f[2]
(你看不懂?我来解释,2处理后有两个数 2和12 ,我们就是在6左边加上了2(26)和12(126))
只细观察这六个数:
6 16 26 126 36 136
我们发现,这六个数分别是:
6
6加上f[1](16)
6加上f[2](26,126)
6加上f[3](36,136)
所以,f[6]=f[1]+f[2]+f[3]
让我们思考一下,如果数字是奇数
那么f[i]=f[i-1]
因为如果i是奇数,那么i/2==(i-1)/2
那i前面能加的数字和i-1能加的数字就是一样的
5+3
5=
5
15
25
125
3=
3
13
如果n是偶数,那么f[n]=f[i-1]+f[i/2];
举个例子,如果比如6的时候
按照公式,我们f[6]=f[5]+f[3]
其中,f[5]代表5左边能加上的所有可能(最大加上2)
f[3]代表3左边能加上的所有可能(因为3=6/2,所以这里我们对于6来说,f[3]是6左边加上3能有多少种可能)
于是我们就算出来了
(怎么说呢,好像写的乱乱的,如果有人没看懂,我很抱歉其实我自己也忘记自己怎么做的了)
文章末尾有某些东西
代码:
#include <bits/stdc++.h>
using namespace std;
long long n;
long long f[1010];
int main() {
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin >> n;
f[1]=1;
for(int 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];
return 0;
}
文章结束了
你在看什么?
你在期待什么?
本人尊师敬长,热心帮助同学,与同学相处融洽,担任小组长,能协助老师收好作业,学习上我严格要求自己,制定好明确的目标,并为这个目标付出努力,遇到什么困难都不放弃,分析、解决问题能力强,成绩优良,学习使我增长了知识,培养了各方面的能力,学习也使我认清了自己的缺点,那就是解决问题是不够细心。
生活上,我严格要求自己,以《中小学生守则》和《中学生日常行为规范》来约束自己的言行;我关心自己的身体状况,养成健康的生活方式,为人真诚友好,结交了许多朋友朋友,我珍视自己的兴趣爱好,丰富了课余生活。
2023年福建省机器人设计与应用交流活动中获得c++编程项目一等奖。