• 洛谷P1464_Function 记忆化搜索


    洛谷P1464_Function

    本次随笔专门讨论记忆化搜索

    记忆化搜索常常和dp+递归结合,用来解决重复冗余问题。目的是加快搜索效率,避免tle。但是在数据范围较大的dp中使用会仍然有问题,比如爆栈(递归太深)

    基本思路是通过一个记录状态的数组/记录答案的数组,保存前一阶段的状态/结果,从而在后一阶段的调用中直接获得答案,而不是重新调用递归。

    我的代码:

    其中注释部分是AC代码,而非注释部分是另外一种更为简便的记忆化方法

     1 #include<iostream>
     2 using namespace std;
     3 typedef long long ll;
     4 const int N=1000;
     5 int w[25][25][25]={{{}}};
     6 struct var{
     7     ll a;
     8     ll b;
     9     ll c;
    10 }g[N]; 
    11 //记忆化搜索
    12 int func(ll a,ll b,ll c){
    13     if(a<=0||b<=0||c<=0){
    14         return 1;
    15     }
    16     else if(a>20||b>20||c>20)  return func(20,20,20);
    17     else{
    18         if(w[a][b][c]>0)  return w[a][b][c];
    19         else if(a<b&&b<c){ 
    20 //            w[a][b-1][c-1]=func(a,b-1,c-1);
    21 //            w[a][b][c-1]=func(a,b,c-1);
    22 //            w[a][b-1][c]=func(a,b-1,c);
    23             w[a][b][c] = func(a,b-1,c-1)+func(a,b,c-1)-func(a,b-1,c);
    24 //            return w[a][b-1][c-1]+w[a][b][c-1]-w[a][b-1][c];
    25         }
    26         else{
    27 //            w[a-1][b-1][c-1]=func(a-1,b-1,c-1);
    28 //            w[a-1][b][c-1]=func(a-1,b,c-1);
    29 //            w[a-1][b-1][c]=func(a-1,b-1,c);
    30 //            w[a-1][b][c]=func(a-1,b,c);
    31             w[a][b][c]=func(a-1,b,c-1)+func(a-1,b-1,c)+func(a-1,b,c)-func(a-1,b-1,c-1);
    32 //            return w[a-1][b][c]+w[a-1][b-1][c]+w[a-1][b][c-1]-w[a-1][b-1][c-1];
    33         }
    34         return w[a][b][c];
    35     }
    36 }
    37 int main(){
    38     w[0][0][0]=1;
    39     int i;
    40     for(i=0;;i++){
    41         cin >> g[i].a >> g[i].b >> g[i].c;
    42         if(g[i].a==-1&&g[i].b==-1&&g[i].c==-1){
    43             break;
    44         }
    45     }
    46     for(int k=0;k<i;k++){
    47         cout << "w(" << g[k].a << ", " << g[k].b << ", " << g[k].c << ") = " << func(g[k].a,g[k].b,g[k].c) << endl;
    48     }
    49     return 0;
    50 }

    其实注释部分(我自己的记忆化方法)的本质就是非注释部分。想想看,如果w[a][b][c]没有被计算过,那么肯定会在执行func(a,b,c)时给w[a][b][c]赋值,因此不必还单独给func(a,b-1,c-1)之类的赋值了。

    另外对于记忆化搜索其实还有个值得注意的,就是在一个表达式中涉及多个状态数组值的问题,可以考虑先计算那个小的(也就是本来按顺序就排列在前面的)

    不过好像也没有太大关系,主要自己觉得更顺心一点。

  • 相关阅读:
    我深知黑暗,但心向光明(记毕业后第一次在北京求职)
    CF 1200E HASH模板
    CF580D
    CF1433F
    CF1451 E1交互题
    11.23-11.29 训练计划
    11.22 CF总结 #682
    sql问题:备份集中的数据库备份与现有的 '办公系统' 数据库不同
    内容导出成word
    让超链接无法跳转的方法
  • 原文地址:https://www.cnblogs.com/horizonlc/p/10355498.html
Copyright © 2020-2023  润新知