DP优化大全-J

1.从滚动数组开始

在写动态规划的时,我们有时会发现,我们的代码在世间上很好,但在空间上却存在一些问题,这是因为我们使用了二维数组,一位记录时间,一维记录空间消耗。However,我们不难发现,我们其实没有必要记录时间戳,当我们更新当前节点时,所有的数据都是在之前被更新的,都具有转移的条件。

例题 疯狂的采药
#include<bits/stdc++.h> 
using namespace std;
const int N=1e7+10;
long long w[100010],val[100010];
long long dp[N];
int main(){
    int t,m;
    cin>>t>>m;
    for(int i=1;i<=m;i++){
        cin>>w[i]>>val[i];
    }
    for(int i=1;i<=m;i++) 
        for(int j=0;j<=t;j++){
            if(j>=w[i]){
                dp[j]=max(dp[j-w[i]]+val[i],dp[j]);
            }  
            else
                dp[j]=dp[j];           
        }
    cout<<dp[t]<<endl;
    return 0;
}
2.时间->空间

当我们在动态规划中要调用一个不会更改的值的时候,我们就可以将其预处理进入一个表格,用以空间换时间的方式减少时间复杂度。减小在算法中对同一段或相似区间的开销大的重复性运用。

更特殊的,对于预处理,前缀和是一种实用的算法。前缀和是一个经典的时间压缩技巧,前缀和适用要求满足结合律的,如加法,乘法,异或。前缀和的核心思路是将区间[x,y],看做区间[1,y]-区间[1-x-1],这样的话,我们只需要从一到n循环一遍,做预处理即可。

2.5用整体取代局部

基于区间求和的思想,我们可以在dp上做更多的优化。算法优化的本质是将同样的事情用尽量少的时间完善,这就允许我们更多的利用整体,统一计算的思维。

就比如说,假设我们发现值为1时的情况和值为2时一样,我们就可以将两者合并考虑,从而节省时空复杂度。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值