信息奥赛一本通 1316:【例4.6】数的计数(Noip2001)

这道题需要我们求出符合条件的数的数量有几个,举一个例子16,求满足条件的数一共有几个,

信息奥赛一本通 1316:【例4.6】数的计数(Noip2001)_第1张图片

我们发现每一步的计算都是相同的,那么我们可以使用递归来进行解决,每一个数的满足条件的方案数都等于他前面自然数(不大于数本身的1/2)的方案之和,如果用a[]对每个数的满足条件的数的数量进行存储,那么有a[i]+=a[i-1]+.......,我们求第i个数的满足条件的数的数量只需要循环遍历他前面自然数的数进行累加即可,除此以外我们发现,前面的数1,2,3,的满足条件的数的数量已经求过,产生了冗余的计算,那么就会产生多余的时间浪费可能会导致运行超时,那么我们就可以使用剪枝,来对已经计算过的数据进行存储,下次来求的时候,对其判断,如果已经计算过了,就直接返回即可。那么这个也就是我们递归终止的条件。知道这些我们就可以写递归了,

#include 
using namespace std;
const int N = 1e3 + 10;
#define int long long
int a[N];//这个数可行的方案数
void f(int n) {
    if (a[n]) return;
    a[n] = 1;//本身就算一种方案
    for (int i = 1; i <= n / 2;i++) {
        f(i);//i的方案数
        a[n] += a[i];
    }
}
//1.f(6) a[6]=1 a[6]=a[1]+a[2]+a[3]=6
//2.f(1) a[1]=1 return
//2.f(2) a[2]=1 a[2]+=a[1]=2
//3.f(3) a[3]=1 a[3]+=a[1]=2
signed main() {
    int n; cin >> n;
    f(n);
    cout << a[n] << endl;
    return 0;
}

你可能感兴趣的:(算法)