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 }