CodeVs 1011 数的计算
By MPS
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
题目描述 Description
我们要求找出具有下列性质数的个数(包含输入的自然数n):
先输入一个自然数n(n<=1000),然后对此自然数按照如下方法进行处理:
1. 不作任何处理;
2. 在它的左边加上一个自然数,但该自然数不能超过原数的一半;
3. 加上数后,继续按此规则进行处理,直到不能再加自然数为止.
输入描述 Input Description
一个数n
输出描述 Output Description
满足条件的数的个数
样例输入 Sample Input
6
样例输出 Sample Output
6
数据范围及提示 Data Size & Hint
6个数分别是:
6
16
26
126
36
136
本来不想写解题报告的,毕竟too simple,但是为了巩固递推算法,所以在此特意写了2种算法的解题报告
算法1:记忆化搜索
对于每一层我们只需要搜索1——m/2即可,然后加起来,这里为了避免TLE,特别的,采用了记忆化的手段
代码不再赘述
算法2:递推
f(n)=f(1)+f(2)+f(3)+...+f(n/2)+1 (n≥1)
<归纳法证明>
设F[n]为答案集,则经过观察
f[2]=1(2)+1(12)=2=f[1]+1
f[3]=1(3)+1(13)=2=f[1]+1
f[4]=1(4)+1(24)+1(124)+1(14)=4=f[2]+f[1]+1
.
.
.
易求得:f(n)=f(1)+f(2)+f(3)+...+f(n/2)+1 (n≥1)
初始条件:f(1)=1
时间复杂度O(N(N/2))
代码:
#include <iostream>
using namespace std;
const int MaxN=1001;
long long n,i,j,f[MaxN];
int main(){
cin>>n;
f[1]=1;
for(i=2;i<=n;i++){
f[i]=1;
for(j=1;j<=i/2;j++)
f[i]+=f[j];
}
cout<<f[n]<<endl;
return 0;
}
-----------------------------------------------------------------------------------------------------------------------------------------------------