2019牛客暑期多校训练营(第十场)J - Wood Processing (斜率优化DP)
题意
$n$个宽度为$w_{i}$,高为$h_{i}$ 的 木块,要求分成$k$组,对于每组内的所有木块,高度都变为组内最低木块的高度,宽度保持不变,求变化的最小面积。
分析
由于$dp$状态定义不同写法也不同,这里给出一种解法
高度比较高的木块为迁就高度比较低的(为了$dp$方程及其优化),所以先把木板按照高度从高到低排序
如果设$d[i][k]$ 为前$ i $个分成 $k $份可以保留的最大面积,那么答案就是 $tot−d[n][k]$($tot$ 为初始总面积)
考虑如何转移
$d[i][k]=max(d[j][k-1]+(pre[i]-pre[j])\cdot h[i])$
其中$pre$为宽度前缀和,即$pre[i]=\sum_{1}^{i}w[i] $。
暴力转移复杂度较高($O(n^{2})$),考虑如何优化。(这不就是个斜率优化嘛)
我们设$j_{1}<j_{2}<i$且在计算$dp[i][k]$的时候,决策$j_{2}$更优,也就是说
$d[j_{1}][k−1]+(pre[i]−pre[j_{1}])\cdot h[i]<d[j_{2}][k−1]+(pre[i]−pre[j_{2}])\cdot h[i] $
这时$j_{1}$可以从决策集中被删去,因为后者的$j_{2}$要比$j_{1}$更优。
上式可以化简为
$\frac{d[j_{2}][k-1]-d[j_{1}][k-1]}{pre[j_{2}]-pre[j_{1}]}$>$h[i]$
这时我们维护一个单调递减的决策集就可以了
Code
#include <bits/stdc++.h>
#define empty (head>=tail)
#define ll long long
using namespace std;
const int maxn = 5e3+, maxk = 2e3+;
int n, k, head, tail, j;
ll pre[maxn], d[maxn][maxk], q[maxn];
struct node{int w ,h;}a[maxn];
bool cmp(node a, node b){return a.h > b.h;}
long double slope(int x, int y, int p) {
return (long double)(d[y][p-]-d[x][p-])/(pre[y]-pre[x]);
}
int main()
{
scanf("%d%d", &n, &k);
ll sum = ;
for (int i = ; i<= n; i++) {
scanf("%d%d", &a[i].w, &a[i].h);
sum += a[i].h * a[i].w;
}
sort(a+, a++n, cmp);
for (int i = ; i <= n; i++) pre[i] = pre[i-] + a[i].w;
for(int p = ; p <= k; p++) {
head = tail = ;
for (int i = ; i <= n; i++) {
while(!empty&&slope(q[head],q[head+],p)>a[i].h) head++;
j = q[head]; d[i][p] = d[j][p-]+a[i].h*(pre[i]-pre[j]);
while(!empty&&slope(q[tail],q[tail-],p)<slope(q[tail],i,p)) tail--;
q[++tail] = i;
}
}
printf("%lld\n", sum-d[n][k]);
return ;
}
思考
开始对木板高度排序那里,能想到的应该就直接想到了,没想到的应该是写转移方程的时候发现,排序后比较好写出转移方程,并且需要对其进行优化就会去关心排序的方向。原博主的博客一直都写的挺好的,但是我觉得这种东西还是要多看看各种博客,这会给你广阔的思路和一些对比。他有关斜率优化$dp$的题目里,写的都是由于$A[i]$是单调递增/递减,所以维护的是一个递增/递减的决策集,但是我在相关题目写的挺好的博客里看到的是,博主都是给出说明为什么维护一个凸包/凹包,而并没有说是因为上面的那种原因。另外这题,由于看过维护凸包的,类比的思想维护凹包原理上都是差不多的,不过之后还是要去写凹包相关题目(立flag)。遇到有困惑的地方,重新翻回去看大米饼的博客还有其他人的博客,感觉慢慢会清晰一点,$go\ on$~
2019牛客暑期多校训练营(第十场)J - Wood Processing (斜率优化DP)的更多相关文章
- 2019牛客暑期多校训练营(第二场)E 线段树维护dp转移矩阵
题意 给一个\(n\times m\)的01矩阵,1代表有墙,否则没有,每一步可以从\(b[i][j]\)走到\(b[i+1][j]\),\(b[i][j-1]\),\(b[i][j+1]\),有两种 ...
- 2019牛客暑期多校训练营(第二场) - H - Second Large Rectangle - dp
https://ac.nowcoder.com/acm/contest/882/H 正确的办法:dp1[i][j]表示以i,j为底的矩形的高.得到dp1之后,dp2[i][j]表示以dp1[i][j] ...
- 2019牛客暑期多校训练营(第二场)E.MAZE(线段树+dp)
题意:给你一个n*m的矩阵 你只能向左向右相下走 有两种操作 q次询问 一种是把一个单位翻转(即可走变为不可走 不可走变为可走) 另一种是询问从(1,x) 走到 (n,y)有多少种方案 思路:题目n为 ...
- 2019牛客暑期多校训练营(第六场)J Upgrading Technology
传送门 题意: 就是给你n个技能,每个技能最高升到m级,每升一级就是耗费Cij钱,这个Cij可能是负的,如果所有技能都升到或者说超过j等级,就会获得Dj钱,这个Dj也有可能是负值,让你求你最多得到多少 ...
- 2019牛客暑期多校训练营(第九场)A:Power of Fibonacci(斐波拉契幂次和)
题意:求Σfi^m%p. zoj上p是1e9+7,牛客是1e9: 对于这两个,分别有不同的做法. 前者利用公式,公式里面有sqrt(5),我们只需要二次剩余求即可. 后者mod=1e9,5才 ...
- 2019牛客暑期多校训练营(第一场)A题【单调栈】(补题)
链接:https://ac.nowcoder.com/acm/contest/881/A来源:牛客网 题目描述 Two arrays u and v each with m distinct elem ...
- 2019牛客暑期多校训练营(第一场) B Integration (数学)
链接:https://ac.nowcoder.com/acm/contest/881/B 来源:牛客网 Integration 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 5242 ...
- 2019牛客暑期多校训练营(第一场) A Equivalent Prefixes ( st 表 + 二分+分治)
链接:https://ac.nowcoder.com/acm/contest/881/A 来源:牛客网 Equivalent Prefixes 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/ ...
- 2019牛客暑期多校训练营(第二场)F.Partition problem
链接:https://ac.nowcoder.com/acm/contest/882/F来源:牛客网 Given 2N people, you need to assign each of them ...
- 2019牛客暑期多校训练营(第一场)A Equivalent Prefixes(单调栈/二分+分治)
链接:https://ac.nowcoder.com/acm/contest/881/A来源:牛客网 Two arrays u and v each with m distinct elements ...
随机推荐
- nginx连接资源管理
本文介绍在nginx中连接资源(即ngx_connection_t)的管理与使用. 连接池的初始化 在ngx_cycle_t结构体中维护了几个和连接相关的数据,具体如下 struct ngx_cycl ...
- [剑指offer] 1. 二维数组中的的查找
题目描述 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数 ...
- md文件的书写《一》
标题 :标题大小取决于#的多少 嵌套标题 使用 * - + 中的任一个加空格就可以实现创建列表 多层嵌套 我见青山多妩媚 (右边的尖括号加内容,实现引用) 这是第一段文字. 这是第二段文字. 段落以回 ...
- 线程锁,threadinglocal,线程池,生产者消费者模型
1.线程锁 1.锁Lock(只能锁一次) import threading import time v = [] lock = threading.Lock() def func(arg): lock ...
- jmter快速安装
一.简介 Apache JMeter是Apache组织开发的基于Java的压力测试工具,用于接口和压力测试,所以前提是一定更要安装jdk. 二.下载安装 下载:官网下载 下载完成后运行包里的jmete ...
- 利用Github Pages创建的Jekyll模板个人博客添加阅读量统计功能
目录 前言 准备工作 模板文件修改 写在最后 内容转载自我自己的博客 @(文章目录) 前言 Jekyll 是一个简单的免费的 Blog 生成工具,类似 WordPress .它只是一个生成静态网页的工 ...
- 安装解压版MySQL5.76及以上版本 出现服务正在启动-服务无法启动的问题
最近重装了系统,去MySQL官网下载了最新的MySQL5.7.9,我选择的是解压版,安装之后启动服务的时候,提示服务无法启动,在网上找了很多教程,弄了很久都没有弄好,后来还是决定去英文官网找找答案, ...
- LinkedList实现类
List还有一个LinkedList的实现,它是一个基于链表实现的List类,对于顺序访问集合中的元素进行了优化,特别是当插入.删除元素时速度非常快.因为LinkedList即实现了List接口,也实 ...
- Android:JNI与NDK(二)交叉编译与动态库,静态库
欢迎关注公众号,第一时间获取最新文章: 本篇目录 一.前言 本篇主要以window开发环境为背景介绍一下NDK开发中需要掌握的交叉编译等基础知识,选window系统主要是照顾大多数读者,mac ,li ...
- Linux内核实战(二)- 操作系统概览
不知道你有没有产生过这些疑问: 桌面上的图标到底是啥?凭啥我在鼠标上一双击,就会出来一些不可描述的画面?都是从哪里跑出来的? 凭什么我在键盘上噼里啪啦地敲,某个位置就会显示我想要的那些字符? 电脑怎么 ...