携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第14天,点击查看活动详情
题单名称
【算法1-4】递推与递归
P1028 [NOIP2001 普及组] 数的计算
题目描述
我们要求找出具有下列性质数的个数(包含输入的正整数 )。
先输入一个正整数 (),然后对此正整数按照如下方法进行处理:
-
不作任何处理;
-
在它的左边拼接一个正整数,但该正整数不能超过原数,或者是上一个被拼接的数的一半;
-
加上数后,继续按此规则进行处理,直到不能再加正整数为止。
输入格式
一行,一个正整数 ()。
输出格式
一个整数,表示具有该性质数的个数。
样例 #1
样例输入 #1
6
样例输出 #1
6
提示
【样例解释】
满足条件的数为:,,,,,。
【题目来源】
NOIP 2001 普及组第一题
思路
这题是看了题解才做出来的,真的巧妙
递推式在代码注释里,思想很简单
设一维数组f[i],代表n=i的情况数
就是利用前面数字的情况之和,也就是前缀和,再加上已有数字就构成了我们需要求的数字,注意还需要再加上单数字n的一种情况,就构成了f[n]
递推式为f[i] = f[1] + f[2] + ... + f[i/2]
代码
// P1028 [NOIP2001 普及组] 数的计算
// f[i]表示n=i的情况数
// 可以得到递推式,就是f[i] = f[1] + f[2] + ... + f[i/2]
#include <bits/stdc++.h>
using namespace std;
int main(int argc, char const *argv[])
{
int n;
cin >> n;
int *f = new int[1010]();
// f[0] = 0;
// f[1] = 1;
// int f[1010] = {0,1};
for(int i=2; i<=1000; i++){
for(int j=1; j<=i/2; j++)
f[i] += f[j];
f[i]++;
}
cout << f[n];
return 0;
}