zoukankan      html  css  js  c++  java
  • BZOJ1597 [Usaco2008 Mar]土地购买 [斜率优化]

    土地购买

    题目描述见链接 .


    color{red}{正解部分}

    将 矩形的 作为 xx, 矩形的 作为 yy, 放到 平面直角坐标系 中,
    题目转化 为使用 最小的矩阵面积和 覆盖所有点,

    可以发现当矩形 a,ba, b 满足 a.xb.xa.x le b.xa.yb.ya.y le b.y 时, 矩形 aa 是可以忽略的,
    于是将所有 aa 类矩形代表的坐标从坐标系中抹除, 可以发现剩下的矩形坐标组成了一个 单调递减 的折线,

    然后再使用 最小的矩阵面积和 覆盖所有点,
    这个时候可以发现 覆盖时 按 横坐标 从左到右分成连续的几段进行覆盖是最优的,
    由此可以想到设 F[i]F[i] 表示覆盖前 ii 个点所使用的最小矩形面积和,
    状态转移, F[i]=min(F[k]+cost[k+1,i])F[i] = min(F[k] + cost[k+1, i]), 根据单调性, cost[k+1,i]=hk+1×wicost[k+1, i] = h_{k+1} imes w_i .

    直接转移 时间复杂度 O(N2)O(N^2), 考虑优化, 将方程化简为 F[k]=wi×hk+1+F[i]F[k] = -w_i imes h_{k+1} + F[i],
    可以发现是 斜率优化 的形式, y=F[k],k=wi,x=hk+1,b=F[i]y = F[k], k = -w_i, x = h_{k+1}, b = F[i] .

    目标是使得 F[i]F[i] 最小, 且 斜率负数单调递减, 所以使用 单调队列 维护 下凸包 即可 .


    color{red}{实现部分}

    • 十年 OIOI 一场空, 不开 long longlong long 见祖宗 .
    #include<bits/stdc++.h>
    #define reg register
    typedef long long ll;
    
    const int maxn = 50005;
    
    int N;
    int Tmp_1;
    int que[maxn];
    
    ll F[maxn];
    
    bool vis[maxn];
    
    struct Node{ int h, w; } A[maxn];
    
    bool cmp(Node a, Node b){ return a.w==b.w?a.h<b.h:a.w<b.w; }
    
    double slope(int a, int b){ return (1.0*F[a] - F[b])/(1.0*A[a+1].h - A[b+1].h); }
    
    int main(){
            scanf("%d", &N);
            for(reg int i = 1; i <= N; i ++) scanf("%d%d", &A[i].w, &A[i].h);
            std::sort(A+1, A+N+1, cmp); int max_h = 0;
            for(reg int i = N; i >= 1; i --){ if(A[i].h <= max_h) vis[i] = 1; max_h = std::max(max_h, A[i].h); }
            for(reg int i = 1; i <= N; i ++) if(!vis[i]) A[++ Tmp_1] = A[i];
            N = Tmp_1; int tl = 0, hd = 1; que[++ tl] = 0;
            for(reg int i = 1; i <= N; i ++){
                    double cur_k = -1.0*A[i].w;
                    while(tl-hd+1 >= 2 && slope(que[hd], que[hd+1]) > cur_k) hd ++;
                    F[i] = F[que[hd]] + 1ll*A[que[hd]+1].h*A[i].w;
                    while(tl-hd+1 >= 2 && slope(que[tl-1], i) > slope(que[tl], que[tl-1])) tl --;
                    que[++ tl] = i;
            }
            printf("%lld
    ", F[N]);
            return 0;
    }
    
  • 相关阅读:
    【兼容性】IE不支持日期字符串转换为日期对象
    tinydate.js[v0.2] 优化了调用方式
    tinydate.js[v0.1]关于Javascript Date的工具
    【兼容性】IE10不支持参数默认值即可选参数
    【兼容性】IE10不支持lamda表达式
    创建第一个core项目(netCore学习笔记1)
    .net(C#)在Access数据库中执行sql脚本
    (Lesson2)根据类名称和属性获得元素-JavaScript面向对象
    UWP Tiles
    UWP Ad
  • 原文地址:https://www.cnblogs.com/zbr162/p/11822409.html
Copyright © 2011-2022 走看看