什么是滚动数组

简单来说,滚动数组就是一种具有短暂记忆力的数组,它会牺牲时间来节省空间,用size=3的数组来“存储”30000个数据。这么说有点离谱、抽象,毕竟a[3]怎么存储a[30000]里面的东西呢。这就是滚动数组的特性,即只记录少量的后续需要使用的数据,而将之前用过且不再需要调用的数据抛弃、覆盖,这样就将a[30000]中不要的数据所占的空间节省出来,以达到a[3]就能达成的任务目标。

滚动数组的核心:取余

在开始学习C语音的时候,接触到了一个新的数学运算符:取余%,和除号 / 类似的是都多用在特殊的循环或者是取一串数字的某一位,除法多取高位,取余多取低位。在滚动数组中,取余用于数组下标的动态改变,以达到[3]存[30000]的效果,例如:

int m=30000;//一个原先大的数据空间
int n=3;//所需要的一个滚动数组空间
void fun()
{for (int i = 0; i < m; i++){d[i % n] = d[(i - 1) % n] + d[(i - 2) % n];}
}

通过取余的特点可以看出,动态数组在取模和循环的作用下只用3个空间就可以做到存储30000个数据的作用。

使用情况(浅提动态规划)

那什么时候使用呢?

  1. 在不在意时间,只需要节省空间的情况。滚动数组的本质是通过for循环多次覆盖不用的数值,增加了时间,又使用取余动态改变数组下标,节省了空间。
  2. 多用于动态规划问题(Dynamic Programing,DP)。  

  在这不得不说到动态规划问题,但由于篇幅所限,在此仅浅谈一下,后续有缘更新。DP主要用于求解以时间划分阶段的动态过程的优化问题,但是一些与时间无关的静态规划(如线性规划、非线性规划),只要人为地引进时间因素,把它视为多阶段决策过程,也可以用动态规划方法方便地求解。

多阶段决策过程的特点是每个阶段都要进行决策,具有n个阶段的决策过程的策略是由n个相继进行的阶段决策构成的决策序列。由于前阶段的终止状态又是后一阶段的初始状态,因此确定阶段最优决策不能只从本阶段的效应出发,必须通盘考虑,整体规划。就是说,阶段k的最优决策不应只是本阶段的最优,而必须是本阶段及其所有后续阶段的总体最优。

   而DP 的有最重要的两个理论--最优化原理和无后效性原则

  • 最优化理论,即最优子问题。其思想总结就是最优策略的任何一部分子策略也必须是最优的。举个例子,挑选一段回家的最短路程(最优策略),路上会经过的各种检查点(阶段),该路的任何一个地方到家的路径也是同阶段到家路径的最短路径(子问题最优)。
  • 无后效原则。某阶段的状态旦确定,则此后过程的演变不再受此前各状态及决策的影响。也就是说,“未来与过去无关”(非常好理解)。一个很有意思的点:通过二维数组区分、寄存指定状态,解决后效性问题。

例题说明

斐波那契数列

  1. 因为乘数指定,即只有一条路能走,故符合最优原理。
  2. 乘积固定,没有其它因素影响,所以符合无后效性原则。

因此可以使用滚动数组方法,代码:

void func2()
{int d[3];d[0] = 1;d[1] = 1;for (int i = 0; i < 100; i++){d[i % 3] = d[(i - 1) % 3] + d[(i - 2) % 3];}printf("%d", d[99 % 3]);
}

01背包

  1. 整体最优是由一步步的子问题最优组成,即n个空间的包最优解是由1~n-1个空间背包的最优解组合而成,故符合最优原理。
  2. 每个数值固定,无论前面问题是怎样解,后面背包总空间不变,往后的任何决策都不会改变。故符合无后效性。

因此可以使用滚动数组方法,代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e3+10;
int t,n,v;
int dp[maxn];
int value[maxn];
int weight[maxn];
int main()
{scanf("%d",&t);while(t--){memset(dp,0,sizeof dp);scanf("%d %d",&n,&v);for(int i = 1;i <= n;i++)scanf("%d",&value[i]);for(int i = 1;i <= n;i++)scanf("%d",&weight[i]);// for(int i = 1;i <= n;i++)    原始二维dp方程//     for(int j = 0;j <= v;j++)//     {//         if(j >= weight[i])        //若取得下,则可以选择取或不取//             dp[i][j]=max(dp[i-1][j],dp[i-1][j-weight[i]]+value[i]);//         else//             dp[i][j]=dp[i-1][j];//     }for(int i = 1;i <= n;i++)    //使用滚动数组优化后的dp方程for(int j = v;j >= weight[i];j--)    //倒序保证数据更新的有序性,保证只取一次,正序则是完全背包的写法dp[j]=max(dp[j],dp[j - weight[i]] + value[i]);printf("%d\n",dp[v]);}return 0;
}

最后,滚动数组只是动态问题中的一小部分,后续还有更多有趣的知识,例如动态问题和搜索、分治法的联系和区别。

关于滚动数组的一些初学随笔相关推荐

  1. 洛谷 P2679 子串 【dp神题】【滚动数组】【2015 noip d2t2】

    偷个懒,题解看这里:https://www.luogu.org/problemnew/solution/P2679 看作者 GuessYCB  写的 ===2018.9.6=== 这一次算理解深一点了 ...

  2. 高级打字机【主席树】【滚动数组】【块状链表】

    题目大意: 一个计算机支持一下三中操作: TT xx:在文章末尾打下一个小写字母xx. UU xx:撤销最后的xx次修改操作. QQ xx:询问当前文章中第xx个字母并输出. InputInput 7 ...

  3. 《滚动数组》---滚动数组思想,运用在动态规划当中

    滚动数组是DP中的一种编程思想.简单的理解就是让数组滚动起来,每次都使用固定的几个存储空间,来达到压缩,节省存储空间的作用.起到优化空间,主要应用在递推或动态规划中(如01背包问题).因为DP题目是一 ...

  4. hdu 1024(滚动数组优化)

    本题的大致意思为给定一个数组,求其分成m个不相交子段和最大值的问题. 解题思路:dp[i][j]表示前j个数分成i组,且j在第i组里的最大值. dp[i][j] = max{dp[i][j-1]+a[ ...

  5. HDU 1176 免费馅饼 矩阵取数, dp + 滚动数组

    http://acm.hdu.edu.cn/showproblem.php?pid=1176 首先可以处理出整张地图的状态. book[T][POS]表示第T秒,在第pos个地方有多少个馅饼. dp[ ...

  6. 滚动数组~\(≧▽≦)/~

    今天第一次用了滚动数组,缘由要从一道题说起:POJ 1159 Palindrome 题意:给你一个字符串,求对字符串最少添加几个字符可变为回文串. 分析: 简单做法是直接对它和它的逆序串求最长公共子序 ...

  7. Gym 100507G The Debut Album (滚动数组dp)

    The Debut Album 题目链接: http://acm.hust.edu.cn/vjudge/contest/126546#problem/G Description Pop-group & ...

  8. 动态规划 0-1背包问题 滚动数组

    定义 dp[j]是从物品0到i中挑选物品,放进容量为j的背包中的最大价值总和. 初始化 int dp[maxn]; memset(dp, sizeof(dp), -0x3f3f3f3f); 一维滚动数 ...

  9. Top Secret Task(dp+滚动数组)

    传送门: 题目 dp[i][j][k] 表示 考虑到第i个数 计算前j个数的和 进行了k次操作 则有 若不把第i个数放入前j个数中 dp[i][j][k] = dp[i-1][j][k] 若把第i个数 ...

最新文章

  1. 【Android 安装包优化】使用 lib7zr.a 静态库处理压缩文件 ( 交叉编译 lib7zr.a 静态库 | 安卓工程导入静态库 | 配置 CMakeLists.txt 构建脚本 )
  2. Gson 使用总结 高级用法
  3. 创业者应具备的基本商业知识
  4. java方法示例注释 @_Java 8中的功能接口是什么? @功能注释和示例
  5. 互联网协会点名QQ音乐等14款 App 过度收集用户信息
  6. 软件测试黑盒用例文档,软件测试黑盒白盒测试用例.pdf
  7. java企业级进销存管理系统源码
  8. Programer Cat 福利
  9. 阿里巴巴十周年晚会,马云震撼照片
  10. 用外置的tocat运行springboot项目的四个步骤
  11. 打造高效研发团队 (1) —— 组织架构篇
  12. 九. MySQL InnoDB 底层结构
  13. 综合架构(备份部分)
  14. 屌丝经济”要突破的痛点在哪儿?
  15. 用python进行简单的excel表格分析
  16. 2020年Java最新面试题整理题库完整版
  17. 网上期货开户合约签署流程
  18. 5G纯干货|毫米波概述与优缺点
  19. 赛门铁克:政企云建设与安全要双管齐下
  20. [ 生成函数 ] Codeforces891E Lust

热门文章

  1. 华为手机备忘录有个神奇按钮,按下就能语音转文字,实用又便捷
  2. 使用Muduo完成数独和八数码问题求解服务器
  3. (附源码)计算机毕业设计SSM流浪动物救助及领养平台
  4. 深入理解计算机系统 --- 处理器体系结构
  5. 蒙特卡洛实现python过程_python项目实战:实现蒙特卡罗方法,求物体阴影面积
  6. 软件测试基础(八)测试计划
  7. 点云配准4:cloudcompare的使用以及点云配准功能
  8. oracle中的all_objects,oracle查看所有表all_objects和all_tables的区别
  9. lisp语言如何画小红点_在一个老外微信PM的眼中,中国App UI那些事
  10. 手机打开PDF文档中文英文支持(乱码问题)解决攻略