OVSolitario-io

导航

记忆化:记录子问题的值以避免重复性运算

记忆化搜索(减少重复计算,对搜索的优化)

对于重复子问题,会造成大量的重复性计算(计算以计算的)来导致效率降低
截屏2025-10-23 08.38.18
此时我们可以开记忆数据,将计算过的值存储,并在下次需要的时候使用

此为砍掉重复搜索树图示

截屏2025-10-23 08.42.44
e.g.
截屏2025-10-23 08.37.31

DFS指数级
记忆化保证了每个值只计算一次限制在了NM时间范围内=等价于DP动态规划

好处:不需要考虑循环顺序,且只考虑有解的状态,相较递推效率可能更高
弊端:需要考虑边界,存储all状态,以及不好用滚动数组

记忆化理解:

点击查看代码
记忆化避免重复计算,对于计算过的结果开辟记忆数组存储
本质:若当前x,y相同那么得到结果依然不变,所以对于得到的结果进行记录避免重复计算

记忆数组含义:等价于dfs的含义
如采药:记忆数组即=dfs=采前i株草花费time时间得到的最大收益

记忆化需初始化(memset)

memset原理是将指定内存中值全部设置为指定值,初始指定值只能是0,-1,其余极大值0x7f,极小值0x80,

01搜索:同30分

点击查看代码
void dfs(int now, int times, int worths) {
    if(now > n) {
        if(times <= m) ans = max(ans, worths);
        return ;
    }
    dfs(now + 1, times, worths);
    dfs(now + 1, times + t[now], worths + w[now]);
    return ;
}
点击查看代码
int dfs(int now, int times) {
    int ans;
    if(now == 0) {
        return 0;
    }
    ans = dfs(now - 1, times);
    if(times >= t[now]) {
        ans = max(ans, dfs(now - 1, times - t[now]) + w[now]);
    }
    return ans;
}

int main() {
    cout << dfs(n, m);
}

01记忆化

点击查看代码
int dfs(int now, int times) {
    int ans;
    if(now == 0) {
        return 0;
    }
//判断是否已记忆化    
    if(f[now][times] != -1) return f[now][times];
   
    ans = dfs(now - 1, times);
    if(times >= t[now]) {
        ans = max(ans, dfs(now - 1, times - t[now]) + w[now]);
    }
//记忆化 
    f[now][times] = ans;
    return ans;//也可f[now][times] = ans;写为一步
}
int main() {
    memset(f, -1, sizeof f);
    cout << dfs(n, m);
}

posted on 2025-10-09 19:56  TBeauty  阅读(8)  评论(0)    收藏  举报