POJ3666 线性dp+维度优化
POJ3666 线性dp+维度优化
题面
POJ3666 题面
思路
首先是重要的归纳法寻求思路的思想,在满足S最小化的前提下,假设存在一种构造前k位序列B的方案,即已经构造B1B2⋯BkB_1B_2\cdots B_kB1B2⋯Bk,则对于第Bk+1B_{k+1}Bk+1位可以用如下的构造方法
1)如果Bk≤Ak+1B_{k}\leq A_{k+1}Bk≤Ak+1,则令Bk+1=Ak+1B_{k+1} = A_{k+1}Bk+1=Ak+1,满足单调性且原命题成立
2)如果Bk>Ak+1B_{k}> A_{k+1}Bk>Ak+1,那么两种转移思路:
①如果只由Ak+1A_{k+1}Ak+1一位得出,取Bk+1=BkB_{k+1} = B_{k}Bk+1=Bk
②如果由前面BjBj+1⋯BkB_j B_{j+1}\cdots B_kBjBj+1⋯Bk这些位得出的话,可以由一维数轴求绝对值最值的方法,求得最值是当Bj=Bj+1=⋯=BkB_j =B_{j+1}=\cdots= B_kBj=Bj+1=⋯=Bk时,令这些值等于AjAj+1⋯AkA_j A_{j+1}\cdots A_kAjAj+1⋯Ak的中位数
这里注意到,BiB_iBi都是A中的元素
思路一:
只用一维表示,即dp[i]dp[i]dp[i]表示完成前i个数的构造S的最小值,则有转移方程
dp[i]=min0≤j<i,A[j]≤A[i]{dp[j]+cost(j+1,i−1)}(1)dp[i] = min_{0\leq j<i,A[j]\leq A[i]}\lbrace dp[j]+cost(j+1,i-1) \rbrace \tag{1}dp[i]=min0≤j<i,A[j]≤A[i]{dp[j]+cost(j+1,i−1)}(1)
其中cost(j+1,i-1)表示构造BjBj+1⋯BkB_j B_{j+1}\cdots B_kBjBj+1⋯Bk使得Aj≤Bj≤Bj+1≤⋯≤Bk≤AiA_j\leq B_j\leq B_{j+1}\leq \cdots \leq B_k\leq A_iAj≤Bj≤Bj+1≤⋯≤Bk≤Ai使得∑k=j+1i−1∣Ak−Bk∣\sum_{k = j+1}^{i-1}{\mid A_k-B_k\mid}∑k=j+1i−1∣Ak−Bk∣的最小值
那么下面的工作就是求cost(j+1,i-1),要求整个cost数组,显然只能用朴素算法,遍历i和j,再用k遍历一层i和j之间的所有数AkA_kAk,求中位数,继而求∑k=j+1i−1∣Ak−Bk∣\sum_{k = j+1}^{i-1}{\mid A_k-B_k\mid}∑k=j+1i−1∣Ak−Bk∣(没有考虑决策集合的优化,但是感觉可以优化)
因此这个复杂度为O(N3N^3N3)
思路二:
注意到只把一个维度(已经处理的序列长度)作为“阶段”的要素,需要额外单独构造转移的序列,不足以实现转移,一般这样的情况需要考虑把另一个维度也放在状态里,一个直接的想法就是把B序列的最后一个值也记录在DP状态里面,设F[i,j]表示完成前i个数的构造,其中Bi=jB_i = jBi=j,S的最小值,则转移方程为:
F[i,j]=min0≤k≤j{F[i−1,k]+∣Ai−j∣}(2)F[i,j] = min_{0\leq k\leq j}\lbrace F[i-1,k]+\mid A_i-j \mid \rbrace \tag{2}F[i,j]=min0≤k≤j{F[i−1,k]+∣Ai−j∣}(2)
由于j可能太大,因此需要离散化,把A中出现的数进行离散化,把DP状态中的第二维j的范围降低到O(N),另外,决策集合单调增(参照LCIS),O(1)即可实现转移,因此算法复杂度为O(N2N^2N2)
注意事项
1)离散化的关键是,把原来的dp数组里面的一个维度的数,如本来应该为a[j]替换为j(把本来的1-n映射到a[1]-a[n]),即dp中的j存的是对应a[j]对应的值,用到的重要函数unique表示,”删除”序列中所有相邻的重复元素(只保留一个),并且返回数组的实际长度,正好满足离散化去重的目的
代码(思路二)
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn = 2005;
const ll INF = 2e9;
ll dp[maxn][maxn];
ll a[maxn],a2[maxn];
ll dis[maxn];
ll n,mini = INF,m;
ll abs1(ll a)
{if(a<0)return -a;return a;
}
void init()
{for(int i = 0;i <=n;i++)for(int j = 0;j <=n;j++)dp[i][j] = INF;for(int i = 0;i <=n;i++)dp[0][i] = 0;sort(a2,a2+n);m = unique(a2,a2+n)-a2;
}int main()
{cin >> n;for(int i = 0;i <n;i++)cin >> a[i],a2[i] = a[i];init();for(int i = 1;i <=n+1;i++){mini = dp[i-1][0];for(int j = 0;j <m;j++){mini = min(dp[i-1][j],mini);if(i<=n)dp[i][j] = mini +abs1(a[i-1]-a2[j]);}}cout << mini << endl;return 0;
}
POJ3666 线性dp+维度优化相关推荐
- 【蓝桥杯官网试题 - 算法训练 】K好数(线性dp与优化)
题干: 问题描述 如果一个自然数N的K进制表示中任意的相邻的两位都不是相邻的数字,那么我们就说这个数是K好数.求L位K进制数中K好数的数目.例如K = 4,L = 2的时候,所有K好数为11.13.2 ...
- 寒假算法学习 OI生涯 - 悄无声息(模拟+线性DP优化) OI生涯 - 德国心脏病 (模拟)
OI生涯 - 悄无声息 题目描述 「李」走路是没有动静的,如果你在干「李」不让你干的事情,他会神不知鬼不觉的走到你的身后,然后把你奶一顿! 因为你知道「李」走路没有动静,所以为了提防,可以认为「李」有 ...
- 0x51.动态规划 - 线性DP(习题详解 × 10)
目录 0x51.动态规划 - 线性DP 0x51.1 LIS问题 Problem A. 登山 (最长下降子序列) Problem B. 友好城市(思维) Problem C. 最大上升子序列和 0x5 ...
- POJ - 1050 To the Max(最大连续子段和,线性dp)
题目链接:点击查看 题目大意:给出一个n*n的矩阵,每个点都有一个权值,现在要从中选取一个子矩阵要求权值和最大,问这个最大权值和是多少 题目分析:因为是要求子矩阵的权值和最大的问题,我们可以直接维护一 ...
- 动态规划之线性DP题集
动态规划之线性DP 文章目录 动态规划之线性DP (一)LIS问题 最长上升子序列 (朴素动规) (二分+贪心+动规) 最大子序和 (动规) (贪心) 最长连续递增序列 (动规) (双指针) 俄罗斯套 ...
- MegEngine亚线性显存优化
MegEngine亚线性显存优化 MegEngine经过工程扩展和优化,发展出一套行之有效的加强版亚线性显存优化技术,既可在计算存储资源受限的条件下,轻松训练更深的模型,又可使用更大batch siz ...
- 深度解析MegEngine亚线性显存优化技术
基于梯度检查点的亚线性显存优化方法[1]由于较高的计算/显存性价比受到关注.MegEngine经过工程扩展和优化,发展出一套行之有效的加强版亚线性显存优化技术,既可在计算存储资源受限的条件下,轻松训练 ...
- UVA11584 划分成回文串 Partitioning by Palindromes(线性DP划分+DP判断回文串)
整理的算法模板合集: ACM模板 依旧是线性DP 我们使用闫氏DP分析法 总体DP转移的时间复杂度为O(n2)O(n^2)O(n2). 但是这里牵扯到判断 i\tt ii 到 j\tt jj 是否为回 ...
- 【bzoj5197】[CERC2017]Gambling Guide 期望dp+堆优化Dijkstra
题目描述 给定一张n个点,m条双向边的无向图. 你要从1号点走到n号点.当你位于x点时,你需要花1元钱,等概率随机地买到与x相邻的一个点的票,只有通过票才能走到其它点. 每当完成一次交易时,你可以选择 ...
最新文章
- 常熟理工学院计算机考研,2018江苏专转本考生必看-常熟理工学院介绍
- HTML+CSS+JS实现 ❤️新型冠状病毒射击小游戏❤️
- 关键字 标识符 数据类型
- BAT 厮杀的小程序与手机厂商叫板的快应用,对开发者意味着什么?
- 数据分析Power BI数据可视化教程(二)——关于切片器和地图可视化教程
- android后台倒计时,android倒计时封装(活动进入后台,倒计时依然能正常计时)...
- 【毕业设计】基于stm32的语音识别 - 单片机 嵌入式 物联网 语音识别
- 正态分布的峰度和偏度分别为_关于偏度与峰度的一些探索
- 求ax2+bx+c=0方程的解,要求(1) a=0,不是二次方程。(2) b2-4ac=0,有两个相同的实根。(3)b2-4ac>0,有两个不等的实根。(4)b2-4ac<有两个共轭的复根
- 反编译软件JD-GUI
- 720全景制作 - 微信、PC、移动web
- ios12怎么滑屏解锁_对比苹果iOS12和安卓9.0,相互学习了哪些功能
- 为什么c语言加法错误,分数的加减法——C语言初学者代码中的常见错误与瑕疵(12)...
- 数据分析课设(SPSS,EVIEWS,R)【理论】
- js 二进制、十进制、十六进制的互相转换
- python泰坦尼克号案例分析_Python机器学习案例-泰坦尼克之灾
- 腾讯云域名与个人树莓派设备的动态域名解析
- ios wkweb设置图片_在iOS中使用WKWebView如何支持展示webp格式图片(包括本地html)?...
- oracle段的集合称为,oracle 集合和成员函数 (plsql表也被称为索引表)
- Guid.NewGuid().ToString()的几种格式
热门文章
- ubuntu更换源(清华、中科大、阿里)
- 学习笔记2:高精度地图
- 服务器发布Java jar包
- 计算机应用技术班级介绍,【完满超级团支部】计算机应用技术20-4班开展“点燃青春之火,成就辉煌人生”班级演讲活动...
- ALS算法(推荐系统)
- Matlab基本函数-floor函数
- MYSQL 千万数据速度以及极限测试InnoDb--INSERT 拼接极限(一)
- 设置首字母大写(js)
- 5款好用的mysql客户端
- 第四章 序列式容器(sequence containers)