P1028 数的计算

最开始想到的方法是递归

#include <stdio.h>

int count;
void recur(float n)
{
    if(n/2>=1)
    {
        for(int i=1;i<=n/2;i++)
        {
            count++;
            recur(i);
        }
    }
}

int main()
{
    float n;
    scanf("%f",&n);
    recur(n);
    printf("%d",count+1);
    return 0;
}

但是测评发现大部分会TLE,看了很多大佬的解答,得到了以下两种解决方案:
首先是递归优化,

#include <stdio.h>

int a[1001]={0};
int recur(int n)
{
    int sum=1;
    if(a[n]!=0)
        return a[n];
//    if(n/2.0>=1)写这个判断发现好像并没有什么用
//    {
        for(int i=1;i<=n/2;i++)
        {
            sum+=recur(i);
        }
        a[n]=sum;
        return a[n];
//    }
}

int main()
{
    int n;
    scanf("%d",&n);
    a[1]=1;
    printf("%d",recur(n));
    return 0;
}

递归的本质就是从上往下,触底才反弹,又从下往上,返回答案,这会导致很多的重复计算,和递推的方向是相反的。如果我们加上一个'记忆化搜索'(即使用一个数组,存放曾经计算过的结果,下次遇到同样的计算,直接获取结果了),就能解决这个问题了!


然后是递推

#include <stdio.h>

int main()
{
    int n,i;
    int count[1001]={0,1};
    scanf("%d",&n);
    for(i=2;i<=n;i++)
    {
        //找到规律就很简单了:
        //当i为奇数时f[i]=f[i-1],当i为偶数时f[i]=f[i-1]+f[i/2]
        count[i]=count[i-1];
        if(i%2==0)
            count[i]+=count[i/2];
    }
    printf("%d",count[n]);
    return 0;
}

posted @ 2024-01-29 23:04  Vicky-han  阅读(10)  评论(0编辑  收藏  举报