zoukankan      html  css  js  c++  java
  • BZOJ 1597 [Usaco2008 Mar]土地购买 (斜率优化dp)

    题意:

    给你一些x*y的土地,分成一组一组购买土地,其代价为这组里的max{x}*max{y},问你全部买下最少多少钱

    思路:

    有一个土地为x1*y1,如果存在一个x2*y2,且x1<=x2&&y1<=y2,那么我们就不需要考虑x1*y1的土地了

    这样我们可以处理出一个x单调递增,同时y单调递减的数组

    显然可以看出,每一组购买的土地应该是这个数组中连续的一段

    简单证明:在购买的一组土地总量不变的情况下,该组购买方案为一个单独的x1*y1再加上数组中一段连续的土地[l,r],那么max{x}=a[r].x,而max{y}=y1

    此时一定存在连续的[l-1,r],其max{y}=a[l-1].y<y1,比选择x1*y1更优,所以应该选连续的一段

    所以我们根据新数组,可以写出dp方程:

    f[i]=min(f[j]+a[i].x*a[j+1].y)

    斜率优化即可

    由于a[j+1].y单调递增,我们只需要单调队列维护一个下凸壳

    代码:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    //#include<cmath>
    #include<cstring>
    #include<string>
    #include<stack>
    #include<queue>
    #include<deque>
    #include<set>
    #include<vector>
    #include<map>
        
    #define fst first
    #define sc second
    #define pb push_back
    #define mem(a,b) memset(a,b,sizeof(a))
    #define lson l,mid,root<<1
    #define rson mid+1,r,root<<1|1
    #define lc root<<1
    #define rc root<<1|1
     
    using namespace std;
     
    typedef double db;
    typedef long double ldb;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int       ,int> PI;
    typedef pair<ll,ll> PLL;
     
    const db eps = 1e-6;
    const int mod = 998244353;
    const int maxn = 2e6+100;
    const int maxm = 2e6+100;
    const int inf = 0x3f3f3f3f;
    const ll INF = 0x3f3f3f3f3f3f3f3f;
    //const db pi = acos(-1.0);
     
    int n;
    PLL a[maxn],b[maxn];
    ll f[maxn];
    int q[maxn];
    bool cmp(PLL a, PLL b){return a.fst==b.fst?a.sc<b.sc:a.fst<b.fst;}
    int main(){
        scanf("%d", &n);
        for(int i = 1; i <= n; i++){
            scanf("%lld%lld", &a[i].fst, &a[i].sc);
        }
        sort(a+1,a+1+n,cmp);
        int tot=0;
        for(int i = 1; i <= n; i++){
            while(tot&&a[i].sc>=b[tot].sc)tot--;
            b[++tot]=a[i];
        }
        int l=0,r=0;
        for(int i = 1; i <= tot; i++){
            while(l<r&&(f[q[l+1]]-f[q[l]])<=b[i].fst*(b[q[l]+1].sc-b[q[l+1]+1].sc))l++;
            int j = q[l];
            f[i]=f[j]+b[i].fst*b[j+1].sc;
            while(l<r&&(f[q[r]]-f[q[r-1]])*(b[q[r]+1].sc-b[i+1].sc)>=(f[i]-f[q[r]])*(b[q[r-1]+1].sc-b[q[r]+1].sc))r--;
            q[++r]=i;
        }
        printf("%lld",f[tot]);
        return 0;
    }
    /*
    4
    100 1
    15 150
    20 5
    1 100
     */
  • 相关阅读:
    jmeter主要函数助手功用说明
    性能测试的分类
    monkey基础
    读《复盘-对过去的事情做思维演练—陈中(著)》感知
    关于postman各功能的说明及用法以及批量执行
    python接口测试-认识POST请求
    关于python3.6上传文件时报错:HTTPSConnectionPool(host='***.org', port=443): Max retries exceeded with url: /post (Caused by SSLError(SSLError(1, '[SSL: CERTIFICATE_VERIFY_FAIL解决办法
    [Tips] Mobaxterm添加本地python使用
    [Tips] docker run时运行shell命令
    [Tips] shell 输入输出重定向
  • 原文地址:https://www.cnblogs.com/wrjlinkkkkkk/p/11312056.html
Copyright © 2011-2022 走看看