zoukankan      html  css  js  c++  java
  • 洛谷P1192台阶问题(逆向递推递归dfs+记忆化)

    题目链接:https://www.luogu.org/problemnew/show/P1192

    题目很有价值,用搜索写的话,可以加深对递归搜索的理解。

    一般这样的递推题规律题可以用:dp或记忆化(我就用记忆化了

    所以啊,用正向递归还是逆向递归,关键看题目有没有规律,递推性!(数据范围,题目求的是否就是要暴力所有情况)

    刚开始,直接正向单向递归dfs,最暴力的原始走,把所有方法都试一遍,走到尾位置,过了一个点超时四个。。

     1 #include <iostream>
     2 #include <string>
     3 #include <algorithm>
     4 #include <iomanip>
     5 #include <cstdio>
     6 #include <cstring>
     7 #include <cmath>
     8 using namespace std;
     9 typedef long long ll;
    10 typedef unsigned long long ull;
    11 const int maxn=1e6+5;
    12 const int mod=100003;
    13 int a[maxn];
    14 int n,k;
    15 int ans;
    16 
    17 void so(int sum,int step)//sum代表已经走的级数,step代表走了几步为了方便输出观察正确方案(可以不要对题目没影响)
    18 {
    19     if(sum==n)
    20     {
    21         ans++;
    22         //for(int i=0;i<=step-1;i++) cout<<a[i]<<' ';//排列输出,方便观察是否正确
    23         //cout<<endl;
    24         return;
    25     }
    26 
    27     for(int i=1;i<=k;i++)
    28     {
    29         if(sum+i>n) break;
    30         //a[step]=i;//排列输出,方便观察是否正确
    31         so(sum+i,step+1);
    32     }
    33 }
    34 
    35 
    36 int main()
    37 {
    38     ios::sync_with_stdio(false); cin.tie(0);
    39 
    40     ans=0;
    41     so(0,0);
    42 
    43     cout<<ans<<endl;
    44 
    45     return 0;
    46 }

    之后又想能不能记忆化保存起来,但好像没办法啊,看了大佬题解后,果然是我太菜。。。

    这是规律题,可以找规律啊,逆向递归dfs然后保存起来啊,逆向递归很容易保存记忆化。(一般正向不行就试试逆向会有惊喜!)

     1 #include <iostream>
     2 #include <string>
     3 #include <algorithm>
     4 #include <iomanip>
     5 #include <cstdio>
     6 #include <cstring>
     7 #include <cmath>
     8 using namespace std;
     9 typedef long long ll;
    10 typedef unsigned long long ull;
    11 const int maxn=1e6+5;
    12 const int mod=100003;
    13 int a[maxn];
    14 int jilu[maxn];
    15 int n,k;
    16 //int ans;
    17 
    18 int so(int sum)//sum代表剩余的级数
    19 {
    20     if(jilu[sum]) return jilu[sum];
    21     //if(sum==0) return 1;//可改写1:有了记忆化开始保存,这句话在这基本么什么用(没记忆化时才有用递归出口)
    22 
    23     int ans=0;
    24     for(int i=1;i<=k;i++)
    25     {
    26         //if(sum-i<0) break;//可改写2:因为从小到大来的,一个<,后面更大一定<,所以可直接退出不用再判断了(可以代替sum-i>0)
    27         if(sum-i>=0)
    28         {
    29             ans=(ans+so(sum-i))%mod;//这一层的方案数=走了一层方案数+下下一层+...+走下k层方案数
    30         }                           //以3或1为例跟一遍就明白!
    31     }
    32     jilu[sum]=ans;
    33     return ans;
    34 }
    35 
    36 
    37 int main()
    38 {
    39     ios::sync_with_stdio(false); cin.tie(0);
    40 
    41     cin>>n>>k;
    42 
    43     jilu[0]=1;//比如从1一步到0,从2一步到0,从k一步到0都是这1种走法
    44     cout<<so(n)<<endl;
    45 
    46     return 0;
    47 }

    完。

  • 相关阅读:
    用代码初始化AE控件许可
    打开shpfile,mdb,sde工作空间
    UESTC_Tournament CDOJ 124
    UESTC_Little Deer and Blue Cat CDOJ 1025
    UESTC_Judgment Day CDOJ 11
    UESTC_One Step Two Steps CDOJ 1027
    UESTC_In Galgame We Trust CDOJ 10
    UESTC_贪吃蛇 CDOJ 709
    UESTC_冰雪奇缘 CDOJ 843
    java 常用API 时间
  • 原文地址:https://www.cnblogs.com/redblackk/p/9815262.html
Copyright © 2011-2022 走看看