什么是DP?

推荐看一下。

正文

滚动数组优化

在一些空间贼小,时间还好的 DP 题目里,会用到优化空间的小技♂巧——滚动数组优化。

滚动数组,顾名思义,一个会滚动的数组,主要是怎样个滚法呢?接下来我先举一个例子:

e.g

最长公共子序列(LCS)

给出两个整数序列,求这两个序列的†最长公共子序列。

†最长公共子序列:多个序列的共有的最长子序列。

这道题我们不难发现:

我们设 \(f_{i,j}\) 为从 \(1\) 到 \(i\) 的 \(a\) 子序列和从 \(1\) 到 \(j\) 的 \(b\) 子序列的 \(LCS\)。

它的状态转移方程即为

\[f_{i,j}=
\begin{cases}
f_{i-1, j-1} + 1 & a[i]=b[j] \\
max(f_{i-1,j},f_{i,j-1}) & a[i]\ne b[j]
\end{cases}
\]

我们发现,状态 \(f_{i,j}\) 只依赖于 \(f_{i-1,\dots}\) 和 \(f_{i,\dots}\),那么既然 \(i-2\) 及以后的状态都没用了,那么我们可以把那之前的状态给滚掉,即把第一维套上个 \(\% 2\),思考一下,这里十分的巧妙。

因为 \(mod\) 常数很大,我们为了优化常数,可以使用位运算,即 \(i\% 2\rightarrow i\&1\),\((i-1)\% 2\rightarrow (i\oplus1)\&1\)

这样我们将巨大的 \(O(n^2)\) 的空间压缩到了 \(O(n)\)。

费用提前计算

在一些题目里,它状态的每一次转移都会产生后效性,所以用普通的DP是做不了的,那么,我们如何解决这个问题呢?

这时,我们有一种策略,就是既然我已经知道未来会被现在影响,那么为什么我不先把将要影响的算了呢?这,就是费用提前计算。

e.g

Luogu 2365 任务安排

题目描述

\(n\) 个任务排成一个序列在一台机器上等待完成(顺序不得改变),这 \(n\) 个任务被分成若干批,每批包含相邻的若干任务。

从零时刻开始,这些任务被分批加工,第 \(i\) 个任务单独完成所需的时间为 \(t_i\)。在每批任务开始前,机器需要启动时间 \(s\),而完成这批任务所需的时间是各个任务需要时间的总和(同一批任务将在同一时刻完成)。

每个任务的费用是它的完成时刻乘以一个费用系数 \(f_i\)。请确定一个分组方案,使得总费用最小。

对于 \(100\%\) 的数据,\(1\le n \le 5000\),\(0 \le s \le 50\),\(1\le t_i,f_i \le 100\)。

我们先设 \(dp_i\) 为前 \(i\) 天的答案,\(time_i\) 为前 \(i\) 天完成后的时间,经过手玩样例过后发现状态转移方程为:

\[dp_i=min\{dp_j+(time_j+s+\sum^i_{k=j+1}t_{k})*\sum^i_{k=j+1}f_k\}
\]

对于 \(time_j\),我们可以表示为:

\[time_j = \sum^j_{k=1}t_k\times f_k+num*s
\]

※ \(num\) 为前 \(i\) 天做的次数。

怎么处理 \(num\) 呢?考虑到在每次做任务时,都会使当前和以后计算的时间加上 \(s\),先不管转移方程,我们现在对未来的影响为:

\[\sum^n_{k=j+1}s\times f_k=s\times\sum^n_{k=j+1} f_k
\]

于是我们可以列出一个船新的状态转移方程:

\[dp_i=min\{dp_j+\sum^i_{k=1}t_k\times\sum^i_{l=j+1}f_l+s\times\sum^n_{k=j+1} f_k\}
\]

因为我们在过去已经计算了影响现在的值,所以我们只需要计算 \(\sum^i_{k=1}t_k\)。以上的各种 \(\sum\) 均可以用前缀和优化为 \(O(1)\) 的,所以时间复杂度为 \(O(n^2)\)。

数位DP

数位DP主要解决的是有关每个数位上的数字的一些关系,这种DP比较容易辨认,大多是一眼题,形如:

求 \(l\) 到 \(r(1\le l,r\le 10^{18})\) 中满足以下性质的数的个数:

每个数位.........

我们可以使用类似前缀和的思想,设 \(dp(i)\) 为 \(1\) 到 \(i\) 一共满足性质的数的个数,答案即为 \(dp(r) - dp(l-1)\)。

发现可以对于一个已经固定最高位了的任意满足条件的 \(k\) 位数的数量进行预处理,但是这个做法会假掉,原因:先设原数等于 \(\overline{kabcd\cdots e}\)(\(x\) 位数),则我们在处理满足性质的最高位为 \(k\) 的 \(x\) 位数的个数可能会包含超出原数范围的数,但是这部分的数是不可取的,并且难以维护 \(\overline{kabcd\cdots e}\) 以内的满足性质的最高位为 \(k\) 的 \(x\) 位数的个数,所以做法假了。

注意到最高位小于 \(k\) 时,我们是可以使用上文预处理的方法的,于是我们可以分类讨论:

列出以上树形图

对于左边的分支,我们可以直接用先前预处理出来的值来更新 \(ans\),对于右边的分支,继续往下走,记录一下前面数位的情况,再针对前面的数位来进行下一位的转移。

e.g.

DP杂谈【持续更新中】的更多相关文章

  1. git常用命令(持续更新中)

    git常用命令(持续更新中) 本地仓库操作git int                                 初始化本地仓库git add .                       ...

  2. Atom使用记录(持续更新中)

    部分内容取自:http://www.jianshu.com/p/dd97cbb3c22d,我自己也在使用,持续更新中 Atom安装插件在窗口中File---Setting---install 在里面进 ...

  3. Pig基础学习【持续更新中】

    *本文参考了Pig官方文档以及已有的一些博客,并加上了自己的一些知识性的理解.目前正在持续更新中.* Pig作为一种处理大规模数据的高级查询语言,底层是转换成MapReduce实现的,可以作为MapR ...

  4. Pig语言基础-【持续更新中】

      ***本文参考了Pig官方文档以及已有的一些博客,并加上了自己的一些知识性的理解.目前正在持续更新中.***   Pig作为一种处理大规模数据的高级查询语言,底层是转换成MapReduce实现的, ...

  5. java视频教程 Java自学视频整理(持续更新中...)

    视频教程,马士兵java视频教程,java视频 1.Java基础视频 <张孝祥JAVA视频教程>完整版[RMVB](东西网) 历经5年锤炼(史上最适合初学者入门的Java基础视频)(传智播 ...

  6. 系列文章:老项目的#iPhone6与iPhone6Plus适配#(持续更新中,更新日期2014年10月12日 星期日 )

    本文永久地址为http://www.cnblogs.com/ChenYilong/p/4020399.html ,转载请注明出处. ********************************** ...

  7. 知道创宇爬虫题--代码持续更新中 - littlethunder的专栏 - 博客频道 - CSDN.NET

    知道创宇爬虫题--代码持续更新中 - littlethunder的专栏 - 博客频道 - CSDN.NET undefined 公司介绍 - 数人科技 undefined

  8. Python开发【第二十三篇】:持续更新中...

    Python开发[第二十三篇]:持续更新中...

  9. 《WCF技术剖析》博文系列汇总[持续更新中]

    原文:<WCF技术剖析>博文系列汇总[持续更新中] 近半年以来,一直忙于我的第一本WCF专著<WCF技术剖析(卷1)>的写作,一直无暇管理自己的Blog.在<WCF技术剖 ...

  10. HBase常见问题答疑解惑【持续更新中】

    HBase常见问题答疑解惑[持续更新中] 本文对HBase开发及使用过程中遇到过的常见问题进行梳理总结,希望能解答新加入的HBaser们的一些疑惑. 1. HTable线程安全吗? HTable不是线 ...

随机推荐

  1. Spring源码分析之getBean

    一.前言 spring作为JAVAEE最核心的框架,是每一个java开发者所必须掌握的,非常重要,本篇从一个简单例子入手,由浅入深的分析spring创建bean的全过程,目标在于彻底搞懂spring原 ...

  2. 如何使用webgl(three.js)实现3D消防、3D建筑消防大楼、消防数字孪生、消防可视化解决方案——第十八课(一)

    序: 又是很久没出随笔文章了,一篇文章有时候整理一天,实在是抽不出来时间. 最近在回顾几年前的项目时,发现这个智慧三维消防可视化项目很有回顾价值,索性就拿出来讲讲. 首先,我们要知道消防里的知识,不是 ...

  3. 量子图形加密算法的MATLAB代码实现

    一.概述 目前主流的量子图形加密算法有量子像素编码算法(Quantum Image Pixel Encoding,QIPE).量子像素置乱算法(Quantum Image Pixel Scrambli ...

  4. 声网 X 在线自习室 同学陪伴、老师监督的在线自习是如何火出圈的?

    实时互联网像触角一样,通过情景的共享延伸开来,链接着我们彼此的线下.线上生活,形成一张不可分割的网络.随着社交直播.在线教育.视频会议成为大众生活不可或缺的一部分的同时,智能手表.智能作业灯.视频双录 ...

  5. 【LeetCode贪心#09】用最少数量的箭引爆气球(涉及区间重叠情况判断)

    用最少数量的箭引爆气球 力扣题目链接(opens new window) 在二维空间中有许多球形的气球.对于每个气球,提供的输入是水平方向上,气球直径的开始和结束坐标.由于它是水平的,所以纵坐标并不重 ...

  6. java 企业级开发中常见的注入方式

    1.Spring 注入有四种方式: ・set 注入 这是最简单的注入方式,假设有一个 SpringAction,类中需要实例化一个 SpringDao 对象,那么就可以定义一个 private 的 S ...

  7. ACM-位运算符-判断奇偶

    同样一个问题,位运算可以提高程序的运行效率. 下面讲一下关于奇偶性的判断. 常规方法 public static boolean isOdd(int i){ ​ return i % 2 != 0; ...

  8. FreeSWITCH的originate命令解析及示例

    FreeSWITCH版本:1.10.9 操作系统:CentOS 7.6.1810 originate经常用于发起呼叫,在实际工作过程中用到的也比较多,今天总结下基本用法,也方便我以后查阅. 一.wik ...

  9. 新旧版本功能对比 | v1.5.0 全新升级

    Hi~社区的小伙伴们大家好呀! CloudQuery 最新 1.5.0 社区版本即将于 4月14日 发布,正式上线前,我们迫不及待与大家分享与 v1.4 相比,v1.5.0 在性能和功能上有哪些更新和 ...

  10. 五月十四号java基础知识点

    class Person{ private String name; private int age; public Person(String name,int age){ this.name = ...