zoukankan      html  css  js  c++  java
  • 土地购买[Usaco2008 Mar]

                                                           题目传送门

     

    1597: [Usaco2008 Mar]土地购买

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 5925  Solved: 2243
    [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.

    HINT

     

    Source

     

      首先我们看到每组选择的土地可以是不连续的,这给我们造成了不小的麻烦。

      我们思考一下题意,可以发现若一个矩形的长和宽都不大于另一个矩形的长和宽,那么这个矩形就不用考虑了。

      怎么删除这些无用矩形呢?

      我们先按长为第一关键字,宽为第二关键字进行降序排序,然后就可以比较轻松地删去无用矩形。

      而且我们可以发现最后得到的序列的长单调递减,宽单调递增。也就是说如果选其中两个矩形为一组,序列中位于这两个矩形中间的矩形都是可以免费加入改组的。所以每一组的区间就是连续的。

      于是我们就可以用f[i]表示购买前i块土地的最小花费。转移方程为f[i] = min{f[j]+l[j+1]*r[i]}.

      但这样转移复杂度是O(n^2)的,还是不满足数据要求。

      所以我们考虑斜率优化。状态转移复杂度优化为O(n).  (还没学习斜率优化的同学可以看一下大米饼的博客,强烈推荐。传送门

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #define LL long long
     6 #define RI register int
     7 using namespace std;
     8 const int INF = 0x7ffffff ;
     9 const int N = 50000 + 10 ;
    10 
    11 inline int read() {
    12     int k = 0 , f = 1 ; char c = getchar() ;
    13     for( ; !isdigit(c) ; c = getchar())
    14       if(c == '-') f = -1 ;
    15     for( ; isdigit(c) ; c = getchar())
    16       k = k*10 + c-'0' ;
    17     return k*f ;
    18 }
    19 struct data {
    20     LL l, r ;
    21 }gg[N], hh[N] ;
    22 int n ; int q[N] ; LL f[N] ;
    23 
    24 inline double X(int i) { return -hh[i+1].l ; }
    25 inline double Y(int i) { return f[i] ; }
    26 inline double Rate(int i,int j) { return (Y(j)-Y(i))/(X(j)-X(i)) ; }
    27 
    28 inline bool cmp1(data s,data t) { return s.l == t.l ? s.r > t.r : s.l > t.l ; }
    29 int main() {
    30     n = read() ;
    31     for(int i=1;i<=n;i++) gg[i].l = read(), gg[i].r = read() ;    
    32     sort(gg+1,gg+n+1,cmp1) ; int tt = 0 ;
    33     for(int i=1;i<=n;) {
    34         hh[++tt] = gg[i] ;  int j=i+1 ;
    35         while(gg[j].l <= gg[i].l && gg[j].r <= gg[i].r) j++ ;
    36         i = j ;
    37     }  n = tt ;
    38     int head = 1, tail = 1 ; q[1] = 0 ;
    39     for(int i=1;i<=n;i++) {
    40         while(head < tail && Rate(q[head],q[head+1]) < hh[i].r) head++ ;
    41         int j = q[head] ; f[i] = f[j]+hh[j+1].l*hh[i].r ;
    42         while(head < tail && Rate(q[tail-1],q[tail]) > Rate(q[tail],i)) tail-- ;
    43         q[++tail] = i ;
    44     }
    45     printf("%lld",f[n]) ;
    46     return 0 ;
    47 }
  • 相关阅读:
    使用Mint-UI的Loadmore实现上拉加载更多和下拉刷新
    JavaScript的日常所得
    web网站性能优化整理
    ArrayBuffer
    Blob
    FormData
    FileReader
    websocket的实践
    Vue CLI 3的Vue.config.js
    css行高line-height的一些深入理解及应用
  • 原文地址:https://www.cnblogs.com/zub23333/p/8818956.html
Copyright © 2011-2022 走看看