• bzoj1597 [Usaco2008 Mar]土地购买


    1597: [Usaco2008 Mar]土地购买

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 5716  Solved: 2160
    [Submit][Status][Discuss]

    Description

    农夫John准备扩大他的农场,他正在考虑N (1 <= N <= 50,000) 块长方形的土地. 每块土地的长宽满足(1 <= 宽 <
    = 1,000,000; 1 <= 长 <= 1,000,000). 每块土地的价格是它的面积,但FJ可以同时购买多快土地. 这些土地的价
    格是它们最大的长乘以它们最大的宽, 但是土地的长宽不能交换. 如果FJ买一块3x5的地和一块5x3的地,则他需要
    付5x5=25. FJ希望买下所有的土地,但是他发现分组来买这些土地可以节省经费. 他需要你帮助他找到最小的经费.

    Input

    * 第1行: 一个数: N
    * 第2..N+1行: 第i+1行包含两个数,分别为第i块土地的长和宽

    Output

    * 第一行: 最小的可行费用.

    Sample Input

    4
    100 1
    15 15
    20 5
    1 100
    输入解释:
    共有4块土地.

    Sample Output

    500
    FJ分3组买这些土地:
    第一组:100x1,
    第二组1x100,
    第三组20x5 和 15x15 plot.
    每组的价格分别为100,100,300, 总共500.
    分析:挺好的一道题!
       土地的长和宽是两个影响因素,一起处理很难,先尝试消除一个因素的影响:按照长从大到小排序.这样就能够写一个dp转移方程
    f(i) = min{max{w[k]} * l[j + 1] + f(j)}  (j+1≤k≤i). O(n^2)的复杂度,难以通过本题.
       尝试一下优化,这个似乎可以决策单调性搞一搞?推一推有关w的式子发现并不一定成立. 怎么办?换个角度.
       将长看作纵坐标,宽看作横坐标,往平面直角坐标系上投影. 对于一个点(x,y),如果还存在一个点(x',y'),使得x' ≥ x,y'≥ y,那么点(x,y)就没有存在的价值了. 可以发现,,宽也是有序的了!
       得到新的dp式子:f(i) = min{w[i] * l[j + 1] + f(j)},显然这是可以决策单调性优化的,对应经典模型:.套个模板就好啦.
       本题有两个转化,第一个转化还是挺容易看出来的,第二个转化不是很容易想到:两个相互关联的变量可以投影到坐标系上.要多积累这种思想!
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    
    typedef long long ll;
    
    const ll maxn = 50010;
    
    struct node
    {
        ll a,b;
    }e[maxn],s[maxn];
    
    struct node2
    {
        ll l,r,p;
    }q[maxn];
    
    int n;
    ll maxx,tot,f[maxn],cur,top;
    
    bool cmp(node a,node b)
    {
        if(a.a == b.a)
            return a.b > b.b;
        return a.a > b.a;
    }
    
    ll calc(ll x,ll y)
    {
        return f[x] + s[x + 1].a * s[y].b;
    }
    
    int find(node2 temp,int pos)
    {
        ll l = temp.l,r = temp.r,ans = temp.r + 1;
        while (l <= r)
        {
            ll mid = (l + r) >> 1;
            if (calc(pos,mid) < calc(temp.p,mid))
            {
                ans = mid;
                r = mid - 1;
            }
            else
                l = mid + 1;
        }
        return ans;
    }
    
    void solve()
    {
        node2 temp;
        temp.l = 1;
        temp.r = tot;
        temp.p = 0;
        q[++top] = temp;
        cur = 1;
        for (int i = 1; i <= tot; i++)
        {
            if (q[cur].r < i)
                cur++;
            f[i] = calc(q[cur].p,i);
            while (1)
            {
                node2 temp = q[top];
                if (calc(i,temp.r) < calc(temp.p,temp.r))
                {
                    if (calc(i,temp.l) < calc(temp.p,temp.l))
                    {
                        top--;
                        continue;
                    }
                    else
                    {
                        int x = find(temp,i);
                        q[top].r = x - 1;
                        break;
                    }
                }
                else
                    break;
            }
            if (q[top].r < tot)
            {
                node2 temp;
                temp.l = q[top].r + 1;
                temp.r = tot;
                temp.p = i;
                q[++top] = temp;
            }
        }
    }
    
    int main()
    {
        scanf("%d",&n);
        for(int i = 1; i <= n; i++)
            scanf("%lld%lld",&e[i].a,&e[i].b);
        sort(e + 1,e + 1 + n,cmp);
        for (int i = 1; i <= n; i++)
            if (e[i].b > maxx)
            {
                maxx = e[i].b;
                s[++tot] = e[i];
            }
        solve();
        printf("%lld
    ",f[tot]);
    
        return 0;
    }
     
     
  • 相关阅读:
    Codeforces Round #604(Div. 2,
    简单的三层框架以及使用dbutils进行数据库操作(入门)
    DBUtil数据库工具封装
    GUI 中监听 文本框实时改变的实例
    java基础教程GUI
    Dao层通用化,Spring3.0+Hibernate3.3.2通用Dao层整合
    计算器代码
    记事本应用程序java源代码
    GUI
    dbutils开源项目用法
  • 原文地址:https://www.cnblogs.com/zbtrs/p/8463895.html
Copyright © 2020-2023  润新知