P1028 [NOIP 2001 普及组] 数的计算
题目描述
给出正整数 ,要求按如下方式构造数列:
- 只有一个数 的数列是一个合法的数列。
- 在一个合法的数列的末尾加入一个正整数,但是这个正整数不能超过该数列最后一项的一半,可以得到一个新的合法数列。
请你求出,一共有多少个合法的数列。两个合法数列 不同当且仅当两数列长度不同或存在一个正整数 ,使得 。
输入格式
输入只有一行一个整数,表示 。
输出格式
输出一行一个整数,表示合法的数列个数。
输入输出样例 #1
输入 #1
6
输出 #1
6
说明/提示
样例 1 解释
满足条件的数列为:
数据规模与约定
对于全部的测试点,保证 。
解题:
学到真东西了:为了应对超时的问题:我们可以采用空间换时间的方法(记忆化递归)
#include<bits/stdc++.h>
using namespace std;
//记忆化递归
#define N 10005
int mem[N] = {0};
int f(int n)
{
if(mem[n]!=0) return mem[n];//关键步骤
if(n==1)
{
return mem[n] = 1;
}
if(n==2)
{
return mem[n] = 2;
}
if(n==3)
{
return mem[n] = 2;
}
int result = 1;
for(int i=1;i<=n/2;i++)
{
result+=f(i);
}
return mem[n] = result;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
int n;
cin >> n;
cout << f(n);
return 0;
}