【洛谷题解】P1028 [NOIP2001 普及组] 数的计算

题目链接:[NOIP2001 普及组] 数的计算 - 洛谷

难度:普及-

设计知识点:深搜剪枝,记忆化搜索

题意:

给出正整数 n,要求按如下方式构造数列:

  1. 只有一个数字 n 的数列是一个合法的数列。
  2. 在一个合法的数列的末尾加入一个正整数,但是这个正整数不能超过该数列最后一项的一半,可以得到一个新的合法数列。

请你求出,一共有多少个合法的数列。两个合法数列 a,b 不同当且仅当两数列长度不同或存在一个正整数,使得 i≤∣a∣,使得a[i]不等于b[i]

分析:用普通递归n较大会超时,用记忆化搜索可以将已算的数存到数组中,避免重复计算,减少时间复杂度。

AC代码:

#include 
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<

总结:记忆化搜索,遍历到n/2,进行累加存到a【n】中,减少时间复杂度,最后输出a【n】,即方案数。

你可能感兴趣的:(算法,c++,深度优先)