关于滚动数组的一些初学随笔
什么是滚动数组
简单来说,滚动数组就是一种具有短暂记忆力的数组,它会牺牲时间来节省空间,用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个数据的作用。
使用情况(浅提动态规划)
那什么时候使用呢?
- 在不在意时间,只需要节省空间的情况。滚动数组的本质是通过for循环多次覆盖不用的数值,增加了时间,又使用取余动态改变数组下标,节省了空间。
- 多用于动态规划问题(Dynamic Programing,DP)。
在这不得不说到动态规划问题,但由于篇幅所限,在此仅浅谈一下,后续有缘更新。DP主要用于求解以时间划分阶段的动态过程的优化问题,但是一些与时间无关的静态规划(如线性规划、非线性规划),只要人为地引进时间因素,把它视为多阶段决策过程,也可以用动态规划方法方便地求解。
多阶段决策过程的特点是每个阶段都要进行决策,具有n个阶段的决策过程的策略是由n个相继进行的阶段决策构成的决策序列。由于前阶段的终止状态又是后一阶段的初始状态,因此确定阶段最优决策不能只从本阶段的效应出发,必须通盘考虑,整体规划。就是说,阶段k的最优决策不应只是本阶段的最优,而必须是本阶段及其所有后续阶段的总体最优。
而DP 的有最重要的两个理论--最优化原理和无后效性原则:
- 最优化理论,即最优子问题。其思想总结就是最优策略的任何一部分子策略也必须是最优的。举个例子,挑选一段回家的最短路程(最优策略),路上会经过的各种检查点(阶段),该路的任何一个地方到家的路径也是同阶段到家路径的最短路径(子问题最优)。
- 无后效原则。某阶段的状态旦确定,则此后过程的演变不再受此前各状态及决策的影响。也就是说,“未来与过去无关”(非常好理解)。一个很有意思的点:通过二维数组区分、寄存指定状态,解决后效性问题。
例题说明
斐波那契数列
- 因为乘数指定,即只有一条路能走,故符合最优原理。
- 乘积固定,没有其它因素影响,所以符合无后效性原则。
因此可以使用滚动数组方法,代码:
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背包
- 整体最优是由一步步的子问题最优组成,即n个空间的包最优解是由1~n-1个空间背包的最优解组合而成,故符合最优原理。
- 每个数值固定,无论前面问题是怎样解,后面背包总空间不变,往后的任何决策都不会改变。故符合无后效性。
因此可以使用滚动数组方法,代码:
#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;
}
最后,滚动数组只是动态问题中的一小部分,后续还有更多有趣的知识,例如动态问题和搜索、分治法的联系和区别。
关于滚动数组的一些初学随笔相关推荐
- 洛谷 P2679 子串 【dp神题】【滚动数组】【2015 noip d2t2】
偷个懒,题解看这里:https://www.luogu.org/problemnew/solution/P2679 看作者 GuessYCB 写的 ===2018.9.6=== 这一次算理解深一点了 ...
- 高级打字机【主席树】【滚动数组】【块状链表】
题目大意: 一个计算机支持一下三中操作: TT xx:在文章末尾打下一个小写字母xx. UU xx:撤销最后的xx次修改操作. QQ xx:询问当前文章中第xx个字母并输出. InputInput 7 ...
- 《滚动数组》---滚动数组思想,运用在动态规划当中
滚动数组是DP中的一种编程思想.简单的理解就是让数组滚动起来,每次都使用固定的几个存储空间,来达到压缩,节省存储空间的作用.起到优化空间,主要应用在递推或动态规划中(如01背包问题).因为DP题目是一 ...
- hdu 1024(滚动数组优化)
本题的大致意思为给定一个数组,求其分成m个不相交子段和最大值的问题. 解题思路:dp[i][j]表示前j个数分成i组,且j在第i组里的最大值. dp[i][j] = max{dp[i][j-1]+a[ ...
- HDU 1176 免费馅饼 矩阵取数, dp + 滚动数组
http://acm.hdu.edu.cn/showproblem.php?pid=1176 首先可以处理出整张地图的状态. book[T][POS]表示第T秒,在第pos个地方有多少个馅饼. dp[ ...
- 滚动数组~\(≧▽≦)/~
今天第一次用了滚动数组,缘由要从一道题说起:POJ 1159 Palindrome 题意:给你一个字符串,求对字符串最少添加几个字符可变为回文串. 分析: 简单做法是直接对它和它的逆序串求最长公共子序 ...
- Gym 100507G The Debut Album (滚动数组dp)
The Debut Album 题目链接: http://acm.hust.edu.cn/vjudge/contest/126546#problem/G Description Pop-group & ...
- 动态规划 0-1背包问题 滚动数组
定义 dp[j]是从物品0到i中挑选物品,放进容量为j的背包中的最大价值总和. 初始化 int dp[maxn]; memset(dp, sizeof(dp), -0x3f3f3f3f); 一维滚动数 ...
- Top Secret Task(dp+滚动数组)
传送门: 题目 dp[i][j][k] 表示 考虑到第i个数 计算前j个数的和 进行了k次操作 则有 若不把第i个数放入前j个数中 dp[i][j][k] = dp[i-1][j][k] 若把第i个数 ...
最新文章
- 【Android 安装包优化】使用 lib7zr.a 静态库处理压缩文件 ( 交叉编译 lib7zr.a 静态库 | 安卓工程导入静态库 | 配置 CMakeLists.txt 构建脚本 )
- Gson 使用总结 高级用法
- 创业者应具备的基本商业知识
- java方法示例注释 @_Java 8中的功能接口是什么? @功能注释和示例
- 互联网协会点名QQ音乐等14款 App 过度收集用户信息
- 软件测试黑盒用例文档,软件测试黑盒白盒测试用例.pdf
- java企业级进销存管理系统源码
- Programer Cat 福利
- 阿里巴巴十周年晚会,马云震撼照片
- 用外置的tocat运行springboot项目的四个步骤
- 打造高效研发团队 (1) —— 组织架构篇
- 九. MySQL InnoDB 底层结构
- 综合架构(备份部分)
- 屌丝经济”要突破的痛点在哪儿?
- 用python进行简单的excel表格分析
- 2020年Java最新面试题整理题库完整版
- 网上期货开户合约签署流程
- 5G纯干货|毫米波概述与优缺点
- 赛门铁克:政企云建设与安全要双管齐下
- [ 生成函数 ] Codeforces891E Lust
热门文章
- 华为手机备忘录有个神奇按钮,按下就能语音转文字,实用又便捷
- 使用Muduo完成数独和八数码问题求解服务器
- (附源码)计算机毕业设计SSM流浪动物救助及领养平台
- 深入理解计算机系统 --- 处理器体系结构
- 蒙特卡洛实现python过程_python项目实战:实现蒙特卡罗方法,求物体阴影面积
- 软件测试基础(八)测试计划
- 点云配准4:cloudcompare的使用以及点云配准功能
- oracle中的all_objects,oracle查看所有表all_objects和all_tables的区别
- lisp语言如何画小红点_在一个老外微信PM的眼中,中国App UI那些事
- 手机打开PDF文档中文英文支持(乱码问题)解决攻略