滚动数组

滚动数组

本节将要介绍另一个十分实用的小技巧——滚动数组。它常被用来完成常数优化和减少代码量。假设有如下状态转移方程:
在这里插入图片描述
按照该状态转移方程,可以用二维数组保存其状态值,通过如下代码片段完成其状态的转移(这里仅作说明,不考虑边界情况):

for (int i = 1;i <= n;i ++) {
    for (int j = 1;j <= m;j ++) {
        dp[i][j] = max(dp[i - 1][j + 1],dp[i - 1][j - 1]);
    }
}
int ans = dp[n][m]; 

考虑到每次状态的转移仅与上一行有关,可以将二维数组优化到使用一维数组保存。如下:

for (int i = 1;i <= n;i ++) {
    for (int j = 1;j <= m;j ++) {
        buf[j] = max(dp[j + 1],dp[j - 1]);
    }
    for (int j = 1;j <= m;j ++) { 
        dp[j] = buf[j];
    }
}
int ans = dp[m]; 

如该代码片段所示,将原本二维的状态空间优化到了一维,对应的需要在每次状态转移过后进行一次循环次数为 m 的赋值操作。该操作不仅增加了代码量,还增加了程序的耗时。于是使用滚动数组,对其再次进行优化:
定义大小为 2*m 的数组为其状态空间:int dp[2][M];
初始状态保存在 dp[0][i]中。
设定两个 int 类型指针

    int *src; //源指针
    int *des; //目的指针

由于初始状态保存在 dp 数组的第 0 行中,初始时

 src = dp[1];
 des = dp[0]; 

按照状态转移方程进行状态转移

for (int i = 1;i <= n;i ++) {
    swap(src,des); //交换源和目的指针
    for (int j = 1;j <= m;j ++) {
        des[j] = max(src[j + 1],src[j - 1]);
    }
}
int ans = des[m];

如代码所示,在每次循环进行状态转移之前交换源数组和目的数组的指针,使程序能够正确的从源数组中转移状态到目的数组中。当状态转移完成时,新得到状态保存于目的数组中,但它在下一次循环的状态转移中又将变为源数组,于是在下次状态转移开始前再次交换源数组和目的数组指针,这就是滚动数组的工作原理。

滚动数组这个技巧不仅优化了原始的状态空间,还减少了循环次数节约了程序运行时间,同时对代码量的缩减也有很好的效果,是一个值得学习的小技巧。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值