描述
我们要求找出具有下列性质数的个数(包含输入的自然数nn)。
先输入一个自然数 n (n≤1000),然后对此自然数按照如下方法进行处理:
1· 不作任何处理;
2. 在它的左边加上一个自然数,但该自然数不能超过原数的一半;
3. 加上数后,继续按此规则进行处理,直到不能再加自然数为止。
格式
输入格式
自然数n
输出格式
满足条件的数的个数
样例1
样例输入1
6
样例输出1
6
样例说明
满足条件的数为 6 (此部分不必输出),他们分别是:
(1)6
(2)16
(3)26
(4)126
(5)36
(6)136
限制
每个测试点1s
来源
noip2001普及组第一题
思路:
找到递推公式a[n]=1+a[n/2]+a[n/2-1]+a[n/2-2]..+a[1]即可
1 #include <stdio.h> 2 3 int main() { 4 int n,i,j,t; 5 int a[1010]; 6 a[0]=0;a[1]=1;a[2]=2; 7 scanf ("%d",&n); 8 for (i=3;i<=n;i++) { 9 a[i]=1; 10 t=i/2; 11 for (j=1;j<=t;j++) { 12 a[i]+=a[j]; 13 } 14 } 15 printf ("%d\n",a[n]); 16 return 0; 17 }
当然,通过更进一步对递推公式分析,可以找到规律
a[n]=a[n-1] (n%2 !=0)
a[n]=a[n-1]+a[n/2] (n%2==0)
从而获得O(n)的解法
1 #include <stdio.h> 2 3 int main() { 4 int n,i; 5 int a[1010]; 6 a[0]=0;a[1]=1; 7 scanf ("%d",&n); 8 for (i=2;i<=n;i++) { 9 a[i]=a[i-1]; 10 if (!(i&1)) { 11 a[i]+=a[i/2]; 12 } 13 } 14 printf ("%d\n",a[n]); 15 return 0; 16 }