难度:普及-
设计知识点:深搜剪枝,记忆化搜索
题意:
给出正整数 n,要求按如下方式构造数列:
- 只有一个数字 n 的数列是一个合法的数列。
- 在一个合法的数列的末尾加入一个正整数,但是这个正整数不能超过该数列最后一项的一半,可以得到一个新的合法数列。
请你求出,一共有多少个合法的数列。两个合法数列 a,b 不同当且仅当两数列长度不同或存在一个正整数,使得 i≤∣a∣,使得a[i]不等于b[i]
分析:用普通递归n较大会超时,用记忆化搜索可以将已算的数存到数组中,避免重复计算,减少时间复杂度。
AC代码:
#include <bits/stdc++.h>
using namespace std;
int a[1005];//存储方案数
int n;
void dfs(int n)//深搜剪枝(记忆化搜索)
{
if(a[n]!=0)return;//判断是否求过,如求过直接使用
a[n]=1;//n自己为一种情况
for(int i=1; i<=n/2; i++)
{
dfs(i);//直接跳到dfs(n),i=n
a[n]=a[n]+a[i];//递归式
}
}
int main()
{
cin>>n;
dfs(n);//搜索
cout<<a[n];//输出方案数
return 0;
}
总结:记忆化搜索,遍历到n/2,进行累加存到a【n】中,减少时间复杂度,最后输出a【n】,即方案数。