HDU 3669 Cross the Wall(斜率DP+预处理)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3669
题目大意:有n(n<=50000)个矩形,每个矩形都有高和宽,你可以在墙上最多挖k个洞使得可以通过,问你最小花费(所有挖的洞的h*w之和)是多少。
解题思路:先将所有矩形按宽从大到小,高从大到小,如果一个矩形宽和高都小于等于前面的矩形则肯定会被前面的矩形覆盖(完全放在前面的矩形里),那么这个矩形就可以删掉,因为不影响结果。
最后再倒序,使得宽从小到大,高从大到小,则状态转移方程为:dp[i][j]=min{dp[k][j-1]+a[k+1].h*a[i].w}(j-1<=k<i)。这样写复杂度为O(m*n^2)。发现dp[i][j]存在单调性,可以用斜率DP优化,使得复杂度降为O(m*n)。注意:记得特判当挖洞数增加但总花费不减少时,直接跳出DP,否则很大可能会超时。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
const int N=5e4+;
const int INF=0x3f3f3f3f; int head,tail;
LL dp[N][],q[N]; struct node{
LL w,h;
bool operator <(const node &b)const{
return w==b.w?h>b.h:w>b.w;
}
}a[N],tmp[N]; LL getUP(int m,int k,int j){
return dp[k][j-]-dp[m][j-];
} LL getDOWN(int m,int k){
return a[m+].h-a[k+].h;
} LL getDP(int i,int j,int k){
return dp[k][j-]+a[k+].h*a[i].w;
} int main(){
int n,m;
while(scanf("%d%d",&n,&m)!=EOF){
for(int i=;i<=n;i++){
scanf("%lld %lld",&tmp[i].w,&tmp[i].h);
}
sort(tmp+,tmp++n);
int cnt=;
a[].h=tmp[].h,a[].w=tmp[].w;
//删除会被完全覆盖的矩形
for(int i=;i<=n;i++){
if(a[cnt].h<tmp[i].h){
cnt++;
a[cnt].h=tmp[i].h;
a[cnt].w=tmp[i].w;
}
}
reverse(a+,a++cnt);
for(int i=;i<=cnt;i++){
dp[i][]=a[].h*a[i].w;
}
LL ans=dp[cnt][]; for(int j=;j<=m;j++){
head=tail=;
q[tail++]=j-;
dp[cnt][j]=INF;
for(int i=j;i<=cnt;i++){
while(head+<tail&&getUP(q[head],q[head+],j)<=a[i].w*getDOWN(q[head],q[head+])){
head++;
}
dp[i][j]=getDP(i,j,q[head]);
while(head+<tail&&getUP(q[tail-],i,j)*getDOWN(q[tail-],q[tail-])<=getUP(q[tail-],q[tail-],j)*getDOWN(q[tail-],i)){
tail--;
}
q[tail++]=i;
}
//加一句特判(从超时变成146ms),当挖洞数增多,花费未降低的时候,说明再增加挖洞数也不会降低花费,直接结束DP
if(ans<=dp[cnt][j])
break;
else
ans=dp[cnt][j];
}
printf("%lld\n",ans);
}
return ;
}
HDU 3669 Cross the Wall(斜率DP+预处理)的更多相关文章
- hdu 3669 Cross the Wall(斜率优化DP)
题目连接:hdu 3669 Cross the Wall 题意: 现在有一面无限大的墙,现在有n个人,每个人都能看成一个矩形,宽是w,高是h,现在这n个人要通过这面墙,现在只能让你挖k个洞,每个洞不能 ...
- 动态规划DP的斜率优化 个人浅解 附HDU 3669 Cross the Wall
首先要感谢叉姐的指导Orz 这一类问题的DP方程都有如下形式 dp[i] = w(i) + max/min(a(i)*b(j) + c(j)) ( 0 <= j < i ) 其中,b, c ...
- HDU 3669 [Cross the Wall] DP斜率优化
问题分析 首先,如果一个人的\(w\)和\(h\)均小于另一个人,那么这个人显然可以被省略.如果我们将剩下的人按\(w[i]\)递增排序,那么\(h[i]\)就是递减. 之后我们考虑DP. 我们设\( ...
- HDU 3669 Cross the Wall
题目大意 给定 \(N\) 个矩形的宽和高, \((h_1, w_1), (h_2, w_2), \dots, (h_n w_n)\) . 现需要确定 \(k\) (\(k \le K\), \(K\ ...
- HDU 2993 - MAX Average Problem - [斜率DP]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2993 Consider a simple sequence which only contains p ...
- HDU 3045 picnic cows(斜率DP)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3045 题目大意:有n个数,可以把n个数分成若干组,每组不得小于m个数,每组的价值=除了该组最小值以外每 ...
- HDU 5956 The Elder (树上斜率DP)
题意:给定上一棵树,然后每条边有一个权值,然后每个点到 1 的距离有两种,第一种是直接回到1,花费是 dist(1, i)^2,还有另一种是先到另一个点 j,然后两从 j 向1走,当然 j 也可以再向 ...
- hdu 2993 MAX Average Problem(斜率DP入门题)
题目链接:hdu 2993 MAX Average Problem 题意: 给一个长度为 n 的序列,找出长度 >= k 的平均值最大的连续子序列. 题解: 这题是论文的原题,请参照2004集训 ...
- hdu 3669(斜率优化DP)
Cross the Wall Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 327680/327680 K (Java/Others) ...
随机推荐
- BZOJ1030:[JSOI2007]文本生成器——题解
http://www.lydsy.com/JudgeOnline/problem.php?id=1030 Description JSOI交给队员ZYX一个任务,编制一个称之为“文本生成器”的电脑软件 ...
- selenium - webdriver常用方法
先定位元素,定位元素后,需要对元素进行后续操作,单击按钮/输入文本,等等. from selenium import webdriver driver = webdriver.Chrome() dri ...
- DOM动态增加控件
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <t ...
- postman ubuntu 14.04 安装
https://jingyan.baidu.com/album/e3c78d649735d63c4c85f5e5.html?picindex=1 实测有效---
- linux内核的配置
以2.6.35.7版本的内核为例 总结:.config决定了Make时的条件编译与连接..config文件由两次配置第一次make XX_defconfig 第二次menuconfig. 1.分析源码 ...
- [USACO13NOV] Pogo-Cow
https://www.luogu.org/problem/show?pid=3089 题目描述 In an ill-conceived attempt to enhance the mobility ...
- UVA129 暴力dfs,有许多值得学习的代码
紫书195 题目大意:给一个困难的串,困难的串的定义就是里面没有重复的串. 思路:不需要重新对之前的串进行判重,只需要对当前的加入的字符进行改变即可. 因为是判断字典序第k个的字符串,所以要多一个全局 ...
- 01-UIScrollView01-大图片展示
源代码下载链接:01-UIScrollView01-大图片展示.zip283.7 KB // // MJViewController.m // 01-UIScrollView01-大图 ...
- [bzoj1005][HNOI2008]明明的烦恼-Prufer编码+高精度
Brief Description 给出标号为1到N的点,以及某些点最终的度数,允许在 任意两点间连线,可产生多少棵度数满足要求的树? Algorithm Design 结论题. 首先可以参考这篇文章 ...
- bzoj 3524 可持久化线段树
我们可以先离散化,然后建立权值的可持久化线段树,记录每个数出现的次数,对于区间询问直接判断左右儿子的cnt是不是大于(r-k+1)/2,然后递归到最后一层要是还是大于就有,否则不存在. 反思:挺简单一 ...