zoukankan      html  css  js  c++  java
  • [USACO 2008 MAR] 土地购买

    [题目链接]

             https://www.lydsy.com/JudgeOnline/problem.php?id=1597

    [算法]

            首先将所有土地按长为第一关键字 , 宽为第二关键字排序

            显然 , 当i > j , 且yi >= yj时 , 土地j没有用 , 不妨使用单调栈弹出所有没有用的土地

            用fi表示前i块土地的最小经费

            显然 , fi = min{ fj + aibj }

            斜率优化即可

            时间复杂度 : O(N)

    [代码]

            

    #include<bits/stdc++.h>
    using namespace std;
    #define N 50010
    typedef long long ll;
    typedef long double ld;
    typedef unsigned long long ull;
    const ll inf = 1e18;
    
    struct info
    {
            ll x , y;
    } a[N];
    
    ll n , l , r , top;
    ll f[N];
    ll q[N] , X[N] , Y[N] , s[N];
    
    template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); }
    template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); }
    template <typename T> inline void read(T &x)
    {
        T f = 1; x = 0;
        char c = getchar();
        for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
        for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
        x *= f;
    }
    inline bool cmp(info a , info b)
    {
            if (a.x != b.x) return a.x < b.x;
            else return a.y < b.y;
    }
    
    int main()
    {
            
            read(n);
            for (int i = 1; i <= n; i++)
            {
                    read(a[i].x);
                    read(a[i].y);        
            }
            sort(a + 1 , a + n + 1 , cmp);
            for (int i = 1; i <= n; i++)
            {
                    while (top > 0 && a[i].y >= a[s[top]].y) --top;
                    s[++top] = i;        
            }
            for (int i = 0; i < top; i++)
                    X[i] = -a[s[i + 1]].y;
            q[f[l = r = 1] = 0] = 0;
            for (int i = 1; i <= top; i++)
            {
                    while (l < r && Y[q[l + 1]] - Y[q[l]] <= a[s[i]].x * (X[q[l + 1]] - X[q[l]])) ++l;
                    f[i] = f[q[l]] - a[s[i]].x * X[q[l]];
                    Y[i] = f[i];
                    while (l < r && (Y[i] - Y[q[r]]) * (X[q[r]] - X[q[r - 1]]) <= (Y[q[r]] - Y[q[r - 1]]) * (X[i] - X[q[r]])) --r;
                    q[++r] = i;
            }
            printf("%lld
    " , f[top]);
            
            return 0;
        
    }
  • 相关阅读:
    jQuery 基本选择器
    JavaScriptif while for switch流程控制 JS函数 内置对象
    JavaScrip基本语法
    数据库 存储引擎 表的操作 数值类型 时间类型 字符串类型 枚举集合 约束
    数据库基础知识 管理员 用户登录授权的操作
    粘包的产生原理 以及如何解决粘包问题
    socket TCP DPT 网络编程
    2018年年终总结
    Android技术分享
    No accelerator found
  • 原文地址:https://www.cnblogs.com/evenbao/p/10354212.html
Copyright © 2011-2022 走看看