>传送门<

题意


$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. 洛谷P3150 pb的游戏(1) 题解

    题目链接: https://www.luogu.org/problemnew/show/P3150 分析: 这道题是一道典型的入门博弈论.我们可以进行如下考虑: 先引入一个奇偶的性质: 奇数=奇数+偶 ...

  2. java ServletContextListener 实现UDP监听

    使用spring boot实现项目启动时的监听, UDPListener import java.io.IOException;import java.io.UnsupportedEncodingEx ...

  3. RecyclerView下拉加载集合越界问题

    问题描述 在做毕业设计app中遇到这样一个问题,使用RecyclerView进行下拉加载数据的时候,比如我每次让它加载5条数据,当服务器端数据总数刚好是5的倍数的时候,不会出现下拉加载数据集合越界的问 ...

  4. MySql(Linux)

    百度云:链接:http://pan.baidu.com/s/1jHQtPau    密码:elr8 官方下载网址:http://dev.mysql.com/downloads/mysql/

  5. SQL Server 插入数据时自增长列如何指定数值

    SQL Server 表在导入数据时,有时需要将自增长列指定数值,来保证导入前后的数据完全一致,如何实现? SQL Server 提供了方法: SET IDENTITY_INSERT,允许将显式值插入 ...

  6. WPF滑块控件(Slider)的自定义样式

    前言 每次开发滑块控件的样式都要花很久去读样式代码,感觉有点记不牢,所以特此备忘. 自定义滑块样式 首先创建项目,添加Slider控件. 然后获取Slider的Window样式,如下图操作. 然后弹出 ...

  7. 现代c++与模板元编程

    最近在重温<c++程序设计新思维>这本经典著作,感慨颇多.由于成书较早,书中很多元编程的例子使用c++98实现的.而如今c++20即将带着concept,Ranges等新特性一同到来,不得 ...

  8. java在src/test/resourse下读取properties文件

    package com.jiepu; import java.io.File; import java.net.URISyntaxException; import java.util.Map; im ...

  9. Gunicorn-Django部署

    1. 简单部署 1. sudo pip3 install gunicorn 2. cd 到django项目中 sudo python3 manage.py migrate 3.启动服务:sudo py ...

  10. 佳木斯集训Day6

    T1还是个找规律啊,记下b的个数,然后直接*2%10000000009就好了 #include <bits/stdc++.h> #define mo 1000000007 using na ...