记忆搜索
从字面来理解,记忆搜索就是按照记忆搜索,当某些循环太多了,但是我们可以找到在循环的过程中,
我们会多次来到每个节点,会多次计算这个节点,这个时候我们就可以将这个节点存下来,在下一次
访问的时候,就不用再来计算这个节点了,可以直接利用。这个就是就是俗称的记忆化搜索,开始自己
听到这个词的时候也是懵逼的,但是做到某些题的时候用起来还是比较方便的,这样可以节省很多时间。
下面我们看来一个题,对于初学者可能有点难哦,...............(表示自己第一次做也是看了题解才会做的。)
题目描述
对于一个递归函数w(a,b,c)w(a,b,c)w(a,b,c)
- 如果a≤0a \le 0a≤0 or b≤0b \le 0b≤0 or c≤0c \le 0c≤0就返回值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,c−1)+w(a,b−1,c−1)−w(a,b−1,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(a−1,b,c)+w(a−1,b−1,c)+w(a−1,b,c−1)−w(a−1,b−1,c−1)
这是个简单的递归函数,但实现起来可能会有些问题。当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,-1−1,−1,−1结束。
保证输入的数在[−9223372036854775808,9223372036854775807][-9223372036854775808,9223372036854775807][−9223372036854775808,9223372036854775807]之间,并且是整数。
输出格式:
输出若干行,每一行格式:
w(a, b, c) = ans
注意空格。
输入输出样例
说明
记忆化搜索
在开始的时候,我是按照题目要求直接将这些递归函数写好,但是在运行的时候时间就爆了;
这是才发现如果这样做的话这个递归就会做很多次,但是很多都会是重复的计算,所以这个时候我们就可以
用到记忆化搜索。
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