hdu3669之二维斜率DP

Cross the Wall

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 327680/327680 K (Java/Others)

Total Submission(s): 4176    Accepted Submission(s): 748

Problem Description

“Across the Great Wall, we can reach every corner in the world!” Now the citizens of Rectland want to cross the Great Wall.

The Great Wall is a huge wall with infinite width and height, so the only way to cross is to dig holes in it. All people in Rectland can be considered as rectangles with varying width and height, and they can only dig rectangle holes in the wall. A person can
pass through a hole, if and only if the person’s width and height is no more than the hole’s width and height both. To dig a hole with width W and height H, the people should pay W * H dollars. Please note that it is only permitted to dig at most K holes for
security consideration, and different holes cannot overlap each other in the Great Wall. Remember when they pass through the wall, they must have their feet landed on the ground.

Given all the persons’ width and height, you are requested to find out the minimum cost for digging holes to make all the persons pass through the wall.

Input

There are several test cases. The first line of each case contains two numbers, N (1 <= N <= 50000) and K (1 <= K <= 100), indicating the number of people and the maximum holes allowed to dig. Then N lines followed, each contains two integers wi and
hi (1 <= wi, hi <= 1000000), indicating the width and height of each person.

Output

Output one line for each test case, indicates the minimum cost.

Sample Input

2 1
1 100
100 1
2 2
1 100
100 1

Sample Output

10000
200
/*分析:
对所有人进行h从大到小排序,然后扫描数组的时候只扫描w递增的
如果当前w比前面的w小则该点根本不需要,因为可以随便加入到前面已经开辟的洞中
假定:
dp[i][j]表示前i个人打j个洞耗费的最少面积
则dp[i][j]=Min(dp[k][j-1]+w[i]*h[k+1])
=>dp[i][j]=dp[k][j-1]+w[i]*h[k+1]
这里有w[i]*h[k+1]所以不能直接用单调队列维护最小值
假定k2<k前i个数在k点分割取得最优值,h[k2+1]>=h[k+1]
则满足:
dp[k][j-1]+w[i]*h[k+1]<=dp[k2][j-1]+w[i]*h[k2+1]
=>(dp[k][j-1]-dp[k2][j-1])/(-h[k+1]-(-h[k2+1]))<=w[i]
假定:
y1=dp[k][j-1]
x1=-h[k+1];
y2=dp[k2][j-1]
x2=-h[k2+1];
所以变成(y1-y2)/(x1-x2)<=sum[i]
斜率DP,维护斜率递增(下凸斜率折线)即可
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <queue>
#include <algorithm>
#include <map>
#include <iomanip>
#define INF 1ll<<60
typedef long long LL;
using namespace std;

const int MAX=50000+10;
int n,k,index,head,tail,Id;
LL dp[MAX][2],q[MAX];//dp采用滚动数组形式

struct Node{
    LL w,h;
    bool operator<(const Node &a)const{
        return h>a.h;
    }
}s[MAX];

LL GetY(int k,int k2){
    return dp[k][index^1]-dp[k2][index^1];
}

LL GetX(int k,int k2){
    return s[k2+1].h-s[k+1].h;
}

void DP(){
    index=0;
    memset(dp,0,sizeof dp);
    for(int i=1;i<=n;++i)dp[i][index]=INF;
    for(int j=1;j<=k;++j){
        index=index^1;
        head=tail=0;
        q[tail++]=0;
        Id=0;
        for(int i=1;i<=n;++i){
        	if(s[i].w <= s[Id].w)continue;
        	Id=i;
            while(head+1<tail && GetY(q[head+1],q[head])<=GetX(q[head+1],q[head])*s[i].w)++head;
            dp[i][index]=dp[q[head]][index^1]+s[i].w*s[q[head]+1].h;
            while(head+1<tail && GetY(i,q[tail-1])*GetX(q[tail-1],q[tail-2])<=GetY(q[tail-1],q[tail-2])*GetX(i,q[tail-1]))--tail;
            q[tail++]=i;
        }
    }
}

int main(){
    while(~scanf("%d%d",&n,&k)){
        for(int i=1;i<=n;++i)scanf("%I64d%I64d",&s[i].w,&s[i].h);
        sort(s+1,s+n+1);
        DP();
        printf("%I64d\n",dp[Id][index]);
    }
    return 0;
}
/*
3 1
2 6
4 4
2 2
*/

hdu3669之二维斜率DP,布布扣,bubuko.com

时间: 2024-10-12 04:45:27

hdu3669之二维斜率DP的相关文章

hdu3480之二维斜率优化DP

Division Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 999999/400000 K (Java/Others) Total Submission(s): 2664    Accepted Submission(s): 1050 Problem Description Little D is really interested in the theorem of sets recently. There's a pro

「kuangbin带你飞」专题二十 斜率DP

layout: post title: 「kuangbin带你飞」专题二十 斜率DP author: "luowentaoaa" catalog: true tags: mathjax: true - kuangbin - 动态规划 - 斜率DP 传送门 A.HDU - 3507 Print Article 题意 就是输出序列a[n],每连续输出的费用是连续输出的数字和的平方加上常数M 让我们求这个费用的最小值. 题解 概率DP的入门题,把我搞得要死要活的. 首先dp[i]表示输出前i

hdu3480二维斜率优化DP

Division Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 999999/400000 K (Java/Others) Total Submission(s): 2664    Accepted Submission(s): 1050 Problem Description Little D is really interested in the theorem of sets recently. There's a pro

hdu2829之二维斜率优化DP

T. E. Lawrence was a controversial figure during World War I. He was a British officer who served in the Arabian theater and led a group of Arab nationals in guerilla strikes against the Ottoman Empire. His primary targets were the railroads. A highl

hdu4800_Josephina and RPG(二维状态dp)

/////////////////////////////////////////////////////////////////////////////////////////////////////// 作者:tt2767 声明:本文遵循以下协议自由转载-非商用-非衍生-保持署名|Creative Commons BY-NC-ND 3.0 查看本文更新与讨论请点击:http://blog.csdn.net/tt2767 链接被删请百度: CSDN tt2767 ///////////////

Vijos1392拼拼图的小衫[背包DP|二维信息DP]

背景 小杉的幻想来到了经典日剧<死亡拼图>的场景里……被歹徒威胁,他正在寻找拼图(-.-干嘛幻想这么郁闷的场景……). 突然广播又响了起来,歹徒竟然又有了新的指示. 小杉身为新一代的汤浅,有责任带领大家脱离危险! (若对情节有任何疑问,请观看原剧) 描述 歹徒告诉小杉,他正在寻找的拼图块其实可以拼成N个 有顺序的 完整的拼图. 每个完整的拼图由若干个拼图块组成. 歹徒要求小杉把拼图按拼出的顺序划分成M个集合,一个拼图集合由若干个完整的拼图组成,并且总的拼图块的数目不超过T.并且,构成集合的拼图

【10.17校内测试】【二维数位DP】【博弈论/预处理】【玄学(?)DP】

Solution 几乎是秒想到的水题叻! 异或很容易想到每一位单独做贡献,所以我们需要统计的是区间内每一位上做的贡献,就是统计区间内每一位是1的数的数量. 所以就写数位dp辣!(昨天才做了数字统计不要太作弊啊!) Code #include<bits/stdc++.h> #define LL long long #define mod 1000000007 using namespace std; inline void read(LL &x) { x = 0; char ch = g

HDU 5119 Happy Matt Friends(简单二维dp)

题意不再说了,就是一个二维的dp,维持取最大值是多少. Happy Matt Friends Time Limit: 6000/6000 MS (Java/Others)    Memory Limit: 510000/510000 K (Java/Others) Total Submission(s): 608    Accepted Submission(s): 229 Problem Description Matt has N friends. They are playing a ga

POJ 1661 Help Jimmy(二维DP)

题目链接:http://poj.org/problem?id=1661 题目大意: 如图包括多个长度和高度各不相同的平台.地面是最低的平台,高度为零,长度无限. Jimmy老鼠在时刻0从高于所有平台的某处(高H处)开始下落,它的下落速度始终为1米/秒.当Jimmy落到某个平台上时,游戏者选择让它向左还是向右跑,它跑动的速度也是1米/秒.当Jimmy跑到平台的边缘时,开始继续下落.Jimmy每次下落的高度不能超过MAX米,不然就会摔死,游戏也会结束. 设计一个程序,计算Jimmy到底地面时可能的最