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) ...
随机推荐
- 数据库sharding,横向扩展
学习资料如下: http://www.cnblogs.com/skyme/p/3459765.html http://my.oschina.net/anthonyyau/blog/307165 htt ...
- mysql jdbc 连接url
jdbc url连接地址格式: jdbc:mysql://[host][,failoverhost...][:port]/[database] [?propertyName1][=propertyVa ...
- maven的tomcat插件如何进行debug调试
利用maven来部署工程时,一般采用的是tomcat插件,使项目在tomcat上面运行,那么这个debug调试是如何进行呢? 我们在调试的时候问题: 会提示找不到资源,那么如何进行修改呢,方法两个: ...
- qt4+vs2010 环境搭建
1.安装开发所需的软件: vs2010(包括VS2010SP1dvd1,Visual_Assist_X_10.9.2062.0_Crack等) QT: qt-win-opensource-4.8.5- ...
- PHP调试的时候出现了警告:
It is not safe to rely on the system解决方法,其实就是时区设置不正确造成的,本文提供了3种方法来解决这个问题. 实际上,从PHP 5.1.0开始当对使用date() ...
- [技巧篇]04.使用PowerDesigner逆向生成
- SNS应用好友动态Feed模块设计
转载自:http://libo93122.blog.163.com/blog/static/122189382012112145728902/ 备注:找不到原作者了. 现在大部分SNS网站都有一个功能 ...
- 35 个你也许不知道的 Google 开源项目
转载自:http://blog.csdn.net/cnbird2008/article/details/18953113 Google是支持开源运动的最大公司之一,它们现在总共发布有超过500个的开源 ...
- 查看自己电脑外网IP
连着wifi,在CMD窗口中显示的无线局域网适配器IP很有可能是内网IP.此时可以通过下面方法查看自己的电脑外网IP. 1.前提条件可以上外网: 2.上外网百度,输入IP,进行搜索. 3.查看结果即可 ...
- 杭电多校第七场-J-Sequence
题目描述 Let us define a sequence as belowYour job is simple, for each task, you should output Fn module ...