Function6

题目链接 https://www.luogu.com.cn/problem/P1464

题目描述里有被告知“当a,b,c均为15时,调用的次数将非常的多,你要想个办法才行.

办法就是记忆化搜索:一般说来,动态规划总要遍历所有的状态,而搜索可以排除一些无效状态。更重要的是搜索还可以剪枝,可能剪去大量不必要的状态,因此在空间开销上往往比动态规划要低很多。记忆化算法在求解的时候还是按着自顶向下的顺序,但是每求解一个状态,就将它的解保存下来,以后再次遇到这个状态的时候,就不必重新求解了。这种方法综合了搜索和动态规划两方面的优点,因而还是很有实用价值的

//来自百度“记忆化搜索”

可以归纳为:记忆化搜索=搜索的形式+动态规划的思想


 

放AC代码

 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 using namespace std;
 4 ll a,b,c;
 5 ll dp[25][25][25];
 6 ll w(ll a,ll b,ll c)
 7 {
 8     if(a<=0||b<=0||c<=0) return 1;
 9     if(a>20||b>20||c>20) return w(20,20,20);
10     if(a<b&&b<c)
11     {
12         if(dp[a][b][c-1]==0)
13             dp[a][b][c-1]=w(a,b,c-1);
14         if(dp[a][b-1][c-1]==0)
15             dp[a][b-1][c-1]=w(a,b-1,c-1);
16         if(dp[a][b-1][c]==0)
17             dp[a][b-1][c]=w(a,b-1,c);
18         dp[a][b][c]=dp[a][b][c-1]+dp[a][b-1][c-1]-dp[a][b-1][c];
19     }
20     else
21     {
22         if(dp[a-1][b][c]==0)
23             dp[a-1][b][c]=w(a-1,b,c);
24         if(dp[a-1][b-1][c]==0)
25             dp[a-1][b-1][c]=w(a-1,b-1,c);
26         if(dp[a-1][b][c-1]==0)
27             dp[a-1][b][c-1]=w(a-1,b,c-1);
28         if(dp[a-1][b-1][c-1]==0)
29             dp[a-1][b-1][c-1]=w(a-1,b-1,c-1);
30         dp[a][b][c]=dp[a-1][b][c]+dp[a-1][b-1][c]+dp[a-1][b][c-1]-dp[a-1][b-1][c-1];
31     }
32     return dp[a][b][c];
33 }
34 int main()
35 {
36     while(scanf("%lld%lld%lld", &a, &b, &c))
37     {
38         if(a==-1&&b==-1&&c==-1) return 0;
39         printf("w(%lld, %lld, %lld) = %lld\n",a,b,c,w(a,b,c));
40     }
41     return 0;
42 }

 

posted @ 2022-03-26 14:12  爱吃虾滑  阅读(34)  评论(0编辑  收藏  举报