暑假训练Day3
记忆化搜索:
理解:记忆化搜索是在递归或搜索需要消耗很多资源的时候,在每一次return的时候顺便用一个数组来存放这个节点的数据。在每一次判断的时候判断数组该节点是否为空,不为空就可以直接调用该节点的数组,省去了重复递归或者搜索的时间。
题目①:P1464 Function
AC代码:

#include<bits/stdc++.h> using namespace std; typedef long long ll; ll ans[30][30][30];//存放节点数据,形成记忆 ll w(ll a, ll b, ll c) { if (a <= 0 || b <= 0 || c <= 0) return 1; else if (ans[a][b][c])//不为空就直接返回,说明以前已经找到过答案 return ans[a][b][c]; else if (a > 20 || b > 20 || c > 20) return ans[a][b][c] = w(20, 20, 20); else if (a < b&&b < c) return ans[a][b][c] = w(a, b, c - 1) + w(a, b - 1, c - 1) - w(a, b - 1, c); else return ans[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); } int main() { ll a, b, c; memset(ans, 0, sizeof(ans)); while (scanf("%lld%lld%lld", &a, &b, &c)) { if (a == -1 && b == -1 && c == -1) return 0; printf("w(%lld, %lld, %lld)", a, b, c); if (a > 20)//这样创建数组就可以创建一个a,b,c<22的数组,避免资源的浪费,也可以减少递归次数 a = 21; if (b > 20) b = 21; if (c > 20) c = 21; printf(" = %lld\n", w(a, b, c)); } return 0; }
题目②:P1028 数的计算
AC代码:

#include<bits/stdc++.h> using namespace std; int num[1005]; int dfs(int n) { if (n == 1) return 1; else if (num[n]) return num[n]; else { int sum = 1;//数自己本身 for (int i = 1; i <= n / 2; i++) { if (!num[i]) num[i] = dfs(i); sum += num[i]; } return sum; } } int main() { int n; cin >> n; cout << dfs(n) << endl; return 0; }