zoukankan      html  css  js  c++  java
  • 记忆搜索

    从字面来理解,记忆搜索就是按照记忆搜索,当某些循环太多了,但是我们可以找到在循环的过程中,

    我们会多次来到每个节点,会多次计算这个节点,这个时候我们就可以将这个节点存下来,在下一次

    访问的时候,就不用再来计算这个节点了,可以直接利用。这个就是就是俗称的记忆化搜索,开始自己

    听到这个词的时候也是懵逼的,但是做到某些题的时候用起来还是比较方便的,这样可以节省很多时间。

    下面我们看来一个题,对于初学者可能有点难哦,...............(表示自己第一次做也是看了题解才会做的。)

    题目描述

    对于一个递归函数w(a,b,c)w(a,b,c)w(a,b,c)

    • 如果a≤0a le 0a0 or b≤0b le 0b0 or c≤0c le 0c0就返回值111.
    • 如果a>20a>20a>20 or b>20b>20b>20 or c>20c>20c>20就返回w(20,20,20)w(20,20,20)w(20,20,20)
    • 如果a<ba<ba<b并且b<cb<cb<c 就返回w(a,b,c−1)+w(a,b−1,c−1)−w(a,b−1,c)w(a,b,c-1)+w(a,b-1,c-1)-w(a,b-1,c)w(a,b,c1)+w(a,b1,c1)w(a,b1,c)
    • 其它的情况就返回w(a−1,b,c)+w(a−1,b−1,c)+w(a−1,b,c−1)−w(a−1,b−1,c−1)w(a-1,b,c)+w(a-1,b-1,c)+w(a-1,b,c-1)-w(a-1,b-1,c-1)w(a1,b,c)+w(a1,b1,c)+w(a1,b,c1)w(a1,b1,c1)

    这是个简单的递归函数,但实现起来可能会有些问题。当a,b,ca,b,ca,b,c均为15时,调用的次数将非常的多。你要想个办法才行.

    /* absi2011 : 比如 w(30,−1,0)w(30,-1,0)w(30,1,0)既满足条件1又满足条件2

    这种时候我们就按最上面的条件来算

    所以答案为1

    */

    输入输出格式

    输入格式:

    会有若干行。

    并以−1,−1,−1-1,-1,-11,1,1结束。

    保证输入的数在[−9223372036854775808,9223372036854775807][-9223372036854775808,9223372036854775807][9223372036854775808,9223372036854775807]之间,并且是整数。

    输出格式:

    输出若干行,每一行格式:

    w(a, b, c) = ans

    注意空格。

    输入输出样例

    输入样例#1: 复制
    1 1 1
    2 2 2
    -1 -1 -1
    输出样例#1: 复制
    w(1, 1, 1) = 2
    w(2, 2, 2) = 4

    说明

    记忆化搜索

    在开始的时候,我是按照题目要求直接将这些递归函数写好,但是在运行的时候时间就爆了;

    这是才发现如果这样做的话这个递归就会做很多次,但是很多都会是重复的计算,所以这个时候我们就可以

    用到记忆化搜索。

    AC代码:

    #include<iostream>
    #include<cstring>
    using namespace std;
    long long rpd[25][25][25];//存放已经计算过的数, 
    long long w(long long a,long long b,long long c)
    {
        if(a<=0||b<=0||c<=0) return 1;
        else if(rpd[a][b][c]!=0) return rpd[a][b][c];//判断该组数据的a,b,c是否已经被计算过,如果计算过直接调用; 
     else if(a>20||b>20||c>20)  rpd[a][b][c]=w(20,20,20);//将每一个大于20的数计算出来并存放进数组中; 
     else if(a<b&&b<c)  rpd[a][b][c]=w(a,b,c-1)+w(a,b-1,c-1)-w(a,b-1,c);//将计算出来的w(a,b,c)存进三维数组的相应下标 
     else  rpd[a][b][c]=w(a-1,b,c)+w(a-1,b-1,c)+w(a-1,b,c-1)-w(a-1,b-1,c-1);
     return rpd[a][b][c];
    }
    int main()
    {    
        
     long long a,b,c,x,y,z;
     while(1)
     { 
     memset(rpd,0,sizeof(rpd));
     cin>>a>>b>>c;
     if(a==-1&&b==-1&&c==-1) break;
     x=a;
     y=b;
     z=c;
     if(a>20) x=21;//超过20的会是一个答案,所以将他记录在同一个位置。
     if(b>20) y=21;
     if(c>20) z=21;
     cout<<"w("<<a<<", "<<b<<", "<<c<<") = "<<w(x,y,z)<<endl;
     }
     return 0;
    }

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

  • 相关阅读:
    SolrCloud阶段总结
    Solr总结
    机器学习算法与Python实践之(六)二分k均值聚类
    机器学习问题方法总结
    浅谈Kmeans聚类
    AVL树的算法思路整理
    Solr4.6从数据库导数据的步骤
    红黑树
    浅谈 Adaboost 算法
    POJ 1836 Alignment
  • 原文地址:https://www.cnblogs.com/zhoubo123/p/11138060.html
Copyright © 2011-2022 走看看