暑假训练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;
}
View Code

 

题目②: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;
}
View Code

 

posted @ 2019-07-04 11:06  夜烛灯花  阅读(127)  评论(0)    收藏  举报