>传送门<

题意


$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)的更多相关文章

  1. 2019牛客暑期多校训练营(第二场)E 线段树维护dp转移矩阵

    题意 给一个\(n\times m\)的01矩阵,1代表有墙,否则没有,每一步可以从\(b[i][j]\)走到\(b[i+1][j]\),\(b[i][j-1]\),\(b[i][j+1]\),有两种 ...

  2. 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] ...

  3. 2019牛客暑期多校训练营(第二场)E.MAZE(线段树+dp)

    题意:给你一个n*m的矩阵 你只能向左向右相下走 有两种操作 q次询问 一种是把一个单位翻转(即可走变为不可走 不可走变为可走) 另一种是询问从(1,x) 走到 (n,y)有多少种方案 思路:题目n为 ...

  4. 2019牛客暑期多校训练营(第六场)J Upgrading Technology

    传送门 题意: 就是给你n个技能,每个技能最高升到m级,每升一级就是耗费Cij钱,这个Cij可能是负的,如果所有技能都升到或者说超过j等级,就会获得Dj钱,这个Dj也有可能是负值,让你求你最多得到多少 ...

  5. 2019牛客暑期多校训练营(第九场)A:Power of Fibonacci(斐波拉契幂次和)

    题意:求Σfi^m%p. zoj上p是1e9+7,牛客是1e9:  对于这两个,分别有不同的做法. 前者利用公式,公式里面有sqrt(5),我们只需要二次剩余求即可.     后者mod=1e9,5才 ...

  6. 2019牛客暑期多校训练营(第一场)A题【单调栈】(补题)

    链接:https://ac.nowcoder.com/acm/contest/881/A来源:牛客网 题目描述 Two arrays u and v each with m distinct elem ...

  7. 2019牛客暑期多校训练营(第一场) B Integration (数学)

    链接:https://ac.nowcoder.com/acm/contest/881/B 来源:牛客网 Integration 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 5242 ...

  8. 2019牛客暑期多校训练营(第一场) A Equivalent Prefixes ( st 表 + 二分+分治)

    链接:https://ac.nowcoder.com/acm/contest/881/A 来源:牛客网 Equivalent Prefixes 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/ ...

  9. 2019牛客暑期多校训练营(第二场)F.Partition problem

    链接:https://ac.nowcoder.com/acm/contest/882/F来源:牛客网 Given 2N people, you need to assign each of them ...

  10. 2019牛客暑期多校训练营(第一场)A Equivalent Prefixes(单调栈/二分+分治)

    链接:https://ac.nowcoder.com/acm/contest/881/A来源:牛客网 Two arrays u and v each with m distinct elements ...

随机推荐

  1. 洛谷 P1635 跳跃

    题目: 题目背景 NOIP即将迎来周年华诞.在这一个春秋的历程里,NOIP领导全国oier,建设高效.稳定.快捷.开放的社会主义现代化OI.在新的一年里,YZOJ将再接再厉,积极探寻成长之路,更好地为 ...

  2. Oracle:ORA-01219:database not open:queries allowed on fixed tables/views only

    Oracle:ORA-01219:database not open:queries allowed on fixed tables/views only 问: 解决 ORA-01219:databa ...

  3. Android/AndroidStudio/idea使用教程之git使用(详细)(码云)

    已经安装好了AndroidStudio,安装教程 本教程是作者自己摸索出来的,有不足之处还请大家海涵.多多拍砖,互相学习. 第一步:下载git,安装git客户端 直接百度git,下载git ​ 安装g ...

  4. java练习---2

    //程序员:罗元昊 2017.9.6public class My{       public static void main(String[] args){              int a= ...

  5. 解决eclipse oxygen+java 10+Tomcat的Could not create the Java virtual machine问题

        本文首发于cartoon的博客     转载请注明出处:https://cartoonyu.github.io/cartoon-blog     这个坑我遇到了两次了,所以就写下来以防自己再遇 ...

  6. java使用栈计算后缀表达式

    package com.nps.base.xue.DataStructure.stack.utils; import java.util.Scanner; import java.util.Stack ...

  7. JAVA对象实例化方式总结

    JAVA对象实例化的方法 New对象实例 // 直接new对象实例 Productor productor = new Productor(); 反射机制 Java反射机制是在运行状态中,对于任意一个 ...

  8. Wpf窗口设置屏幕居中最前显示

    public Window()         {             InitializeComponent();             WindowStartupLocation = Win ...

  9. Hadoop 系列(四)—— Hadoop 开发环境搭建

    一.前置条件 Hadoop 的运行依赖 JDK,需要预先安装,安装步骤见: Linux 下 JDK 的安装 二.配置免密登录 Hadoop 组件之间需要基于 SSH 进行通讯. 2.1 配置映射 配置 ...

  10. 【Java笔记】【Java核心技术卷1】chapter3 D4变量

    package chapter3; public class D4变量 { public static final int BBB=100; //类常量 public static void main ...