土地征用 (Link

约翰准备扩大他的农场,眼前他正在考虑购买N块长方形的土地。如果约翰单买一块土 地,价格就是土地的面积。但他可以选择并购一组土地,并购的价格为这些土地中最大的长 乘以最大的宽。比如约翰并购一块3 × 5和一块5 × 3的土地,他只需要支付5 × 5 = 25元, 比单买合算。 约翰希望买下所有的土地。他发现,将这些土地分成不同的小组来并购可以节省经费。 给定每份土地的尺寸,请你帮助他计算购买所有土地所需的最小费用。
输入输出格式
输入格式:

\(Line\) \(1:\) \(A\) \(single\) \(integer:\) \(N\)
\(Lines\) \(2..N+1:\) \(Line\) \(i+1\) \(describes\) \(plot\) \(i\) \(with\) \(two\) \(space-separated\) \(integers:\) \(width\) _ \(i\) \(and\) \(length\) _ \(i\)
输出格式:
\(Line\) \(1:\) \(The\) \(minimum\) \(amount\) \(necessary\) \(to\) \(buy\) \(all\) \(the\) \(plots.\)

我们定义结构体\(Edge\)中含有\(X,Y\)分别表示一块土地的长和宽。
考虑一块土地\(A\),如果有一块土地\(B\)的\(X\)和\(Y\)都大于\(A\),那么\(A\)的存在是没有意义的,因为\(A\)是可以不耗费任何代价被\(B\)所合并的,所以它不会对答案产生任何影响。于是我们考虑去掉这样所有的土地\(A\)。
首先我们将所有土地按照长度从小到大排序,长度相同的按照宽度从小到大排序。定义一个\(Stack\),然后连续将所有的土地入栈,在\(A\)入栈之前将之前栈中所有宽度小于等于\(A\)的土地全部弹出,然后入栈\(A\)。那么最后在栈中的元素就是我们所希望的元素。这里的元素是按照长度从小到大,宽度从大到小的顺序有序排列的。
那么显然我们每次合并的都是一个连续的区间。考虑使用\(DP\),易得状态转移方程:\(dp[i]=min_{j=1}^{j<=Top}(dp[i],dp[j]+Stack[j+1]*L[i])\),其中Stack里面存的是元素的宽度,L是栈中元素的长度。(因为有些土地被抛弃了所以我们不能继续使用\(Edge\)结构体),然而这样的时间复杂度会超时,考虑斜率优化。
我们看到后面的\(dp[j]+Stack[j+1]*L[i]\),设\(k=Stack[j+1],b=dp[j]\),然后\(x=L[i]\),那么我们就得到了直线方程:\(y=kx+b\)。套上斜率优化的板子即可。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define MAXN 100010
#define LL long long
#define INF 0x7fffffff
using namespace std ;
LL N, Stack[MAXN], Top;
LL dp[MAXN], q[MAXN];
LL A[MAXN], B[MAXN];
LL L[MAXN];
inline void Read(LL & x){
    char C = getchar() ; x = 0 ;
    while(C < '0' || C > '9') C = getchar() ;
    while(C <= '9' && C >= '0')
        x = x * 10 + C - 48, C = getchar() ;
}
inline void Print(LL x){
    LL num = 0 ; char C[15] ;
    while(x) C[++ num] = (x % 10) + 48, x /= 10 ;
    while(num) putchar(C[num --]) ;
    putchar('\n') ;
}
struct Node{
    LL X, Y ;
}Edge[MAXN << 1];
inline bool Cmp(Node A, Node B){
    if(A.X == B.X) return A.Y < B.Y;
    else return A.X < B.X;
}
inline void Put_In_Stack(){
    for(int i = 1; i <= N; i ++){
        while(Top && Stack[Top] <= Edge[i].Y)
            Top -- ;
        Stack[++ Top] = Edge[i].Y ;
        L[Top] = Edge[i].X ;
    }
}
inline double Calc(LL i, LL j){
    return dp[j] + Stack[j + 1] * L[i] ;
}
inline bool Slope(LL a, LL b, LL c){
    return (B[c] - B[a]) * (A[b] - A[a]) - (B[b] - B[a]) * (A[c] - A[a]) >= 0;
}
int main(){
    Read(N) ;
    for(int i = 1; i <= N; i ++){
        Read(Edge[i].X) ;
        Read(Edge[i].Y) ;
    }
    sort(Edge + 1, Edge + N + 1, Cmp) ;
    Put_In_Stack() ;
    A[0] = Stack[1] ;
    LL Head = 1, Tail = 1 ;
    for(int i = 1;i <= Top; i ++){
        while(Head < Tail && Calc(i, q[Head]) >= Calc(i, q[Head + 1]))
            Head ++ ;
        dp[i] = Calc(i, q[Head]) ;
        A[i] = Stack[i + 1] ;
        B[i] = dp[i] ;
        while(Head < Tail && Slope(q[Tail - 1], q[Tail], i))
            Tail -- ;
        q[++ Tail] = i ;
    }
    Print(dp[Top]) ; return 0 ;
}

[LuoguP2900] [USACO08MAR]土地征用(Land Acquisition)的更多相关文章

  1. 洛谷 P2900 [USACO08MAR]土地征用Land Acquisition 解题报告

    P2900 [USACO08MAR]土地征用Land Acquisition 题目描述 约翰准备扩大他的农场,眼前他正在考虑购买N块长方形的土地.如果约翰单买一块土 地,价格就是土地的面积.但他可以选 ...

  2. 洛谷P2900 [USACO08MAR]土地征用Land Acquisition(动态规划,斜率优化,决策单调性,线性规划,单调队列)

    洛谷题目传送门 用两种不一样的思路立体地理解斜率优化,你值得拥有. 题意分析 既然所有的土地都要买,那么我们可以考虑到,如果一块土地的宽和高(其实是蒟蒻把长方形立在了平面上)都比另一块要小,那么肯定是 ...

  3. luogu P2900 [USACO08MAR]土地征用Land Acquisition

    写这道题时,预处理部分少打了等号,吓得我以为斜率优化错了或者被卡精了 mmp 首先有一个很明显的结论(逃),就是一个土地如果长(\(x\))与宽(\(y\))都比另一个土地小,那么这个土地一定可以跟那 ...

  4. 【洛谷 P2900】 [USACO08MAR]土地征用Land Acquisition(斜率优化,单调栈)

    题目链接 双倍经验 设\(H\)表示长,\(W\)表示宽. 若\(H_i<H_j\)且\(W_i<W_j\),显然\(i\)对答案没有贡献. 于是把所有点按\(H\)排序,然后依次加入一个 ...

  5. [USACO08MAR]土地征用Land Acquisition

    题面在这里 题意 约翰准备扩大他的农场,眼前他正在考虑购买N块长方形的土地. 如果约翰单买一块土地,价格就是土地的面积,但他可以选择并购一组土地, 并购的价格为这些土地中最大的长乘以最大的宽. 给定每 ...

  6. 洛谷P2900 [USACO08MAR]土地征用Land Acquisition(斜率优化)

    题意 约翰准备扩大他的农场,眼前他正在考虑购买N块长方形的土地.如果约翰单买一块土 地,价格就是土地的面积.但他可以选择并购一组土地,并购的价格为这些土地中最大的长 乘以最大的宽.比如约翰并购一块3 ...

  7. P2900 [USACO08MAR]土地征用Land Acquisition

    \(\color{#0066ff}{ 题目描述 }\) 约翰准备扩大他的农场,眼前他正在考虑购买N块长方形的土地.如果约翰单买一块土 地,价格就是土地的面积.但他可以选择并购一组土地,并购的价格为这些 ...

  8. Luogu 2900 [USACO08MAR]土地征用Land Acquisition

    斜率优化dp. 首先发现如果存在$x$和$y$使得$len(x) \geq len(y)$并且$wid(x) \geq wid(y)$,那么$y$直接不考虑就好了,因为在买$x$的时候就把$y$顺便带 ...

  9. 洛谷2900 [USACO08MAR]土地征用Land Acquisition (斜率优化+dp)

    自闭的一批....为什么斜率优化能这么自闭. 首先看到这个题的第一想法一定是按照一个维度进行排序. 那我们不妨直接按照\(h_i\)排序. 我们令\(dp[i]\)表示到了第\(i\)个矩形的答案是多 ...

随机推荐

  1. C为什么不能跨平台

    如果大家能对我的文章推荐一下,关注一下本人博客,那就更开心了,我今后也会更多的写一些计算机系统/原理类的文章,以飨各位读者.再次谢谢.前段时间看了 周志明的那本 <深入理解java虚拟机> ...

  2. webpack-loader原理

    loader loader 是导出为一个函数的 node 模块.该函数在 loader 转换资源的时候调用.给定的函数将调用 loader API,并通过 this 上下文访问. loader配置 { ...

  3. Hibernate 性能优化一对一关联映射

    概述: hibernate提供了两种映射一对一关联的方式:按照外键映射和按照主键映射. 下面以员工账号和员工档案为例 ,介绍两种映射方式,并使用这两种映射方式分别完成以下持久化操作: (1)保存员工档 ...

  4. "UTF-8"、"UTF8"、"utf-8"、"utf8"之间的区别

    本质上没有区别.1.“UTF-8”是标准写法;2.在Windows下边英文不区分大小写,所以也可以写成“utf-8”;3.“UTF-8”也可以把中间的“-”省略,写成“UTF8”.一般程序都能识别,但 ...

  5. 06_zookeeper原生Java API使用

    [Zookeeper构造方法概述] /** * 客户端和zk服务端的连接是一个异步的过程 * 当连接成功后,客户端会收到一个watch通知 * * ZooKeeper(String connectSt ...

  6. 安卓基础干货(六):安卓Activity的学习

    AndroidManifest文件中的几个细节 结论: 1.一个应用程序可以创建多个桌面图标 2.创建快捷图标的方法: <intent-filter> //应用程序的入口 <acti ...

  7. 【Python】回文palindrome——利用字符串反转

    回文 palindrome Python 字符串反转string[::-1] Slice notation "[a : b : c]" means "count in i ...

  8. 用Eclipse创建第一个Spring项目(最最入门级)

    http://blog.csdn.net/shymi1991/article/details/48085955 网上关于Spring的介绍资料已经数不胜数,但大多篇幅冗长,初学者不易理解记忆.这里先作 ...

  9. 利用NVM在系统中维护多个版本的nodejs

      0. 背景 开发时可能同时进行多个项目,而这些项目所依赖的node版本又不是一样的.比如我现在的angular项目采用的node是8.9.3版本,而vue项目的vue-cli则依赖更高.由于ang ...

  10. 微软在Build 2016开发者大会中发布 “认知服务”,牛津计划有正式名字啦!

    2016年3月30日:微软在Build 2016开发者大会中发布“认知服务”. 在Build 2016开发者大会中,微软发布了新的智能服务:微软认知服务(Microsoft Cognitive Ser ...