zoukankan      html  css  js  c++  java
  • P2900 [USACO08MAR]土地征用Land Acquisition(斜率优化)

    题目描述

    Farmer John is considering buying more land for the farm and has his eye on N (1 <= N <= 50,000) additional rectangular plots, each with integer dimensions (1 <= width_i <= 1,000,000; 1 <= length_i <= 1,000,000).

    If FJ wants to buy a single piece of land, the cost is $1/square unit, but savings are available for large purchases. He can buy any number of plots of land for a price in dollars that is the width of the widest plot times the length of the longest plot. Of course, land plots cannot be rotated, i.e., if Farmer John buys a 3x5 plot and a 5x3 plot in a group, he will pay 5x5=25.

    FJ wants to grow his farm as much as possible and desires all the plots of land. Being both clever and frugal, it dawns on him that he can purchase the land in successive groups, cleverly minimizing the total cost by grouping various plots that have advantageous width or length values.

    Given the number of plots for sale and the dimensions of each, determine the minimum amount for which Farmer John can purchase all

    约翰准备扩大他的农场,眼前他正在考虑购买N块长方形的土地。如果约翰单买一块土 地,价格就是土地的面积。但他可以选择并购一组土地,并购的价格为这些土地中最大的长 乘以最大的宽。比如约翰并购一块3 × 5和一块5 × 3的土地,他只需要支付5 × 5 = 25元, 比单买合算。 约翰希望买下所有的土地。他发现,将这些土地分成不同的小组来并购可以节省经费。 给定每份土地的尺寸,请你帮助他计算购买所有土地所需的最小费用。

    输入输出格式

    输入格式:

    * Line 1: A single integer: N

    * Lines 2..N+1: Line i+1 describes plot i with two space-separated integers: width_i and length_i

    输出格式:

    * Line 1: The minimum amount necessary to buy all the plots.

    输入输出样例

    输入样例#1: 复制
    4 
    100 1 
    15 15 
    20 5 
    1 100 
    
    输出样例#1: 复制
    500 
    

    说明

    There are four plots for sale with dimensions as shown.

    The first group contains a 100x1 plot and costs 100. The next group contains a 1x100 plot and costs 100. The last group contains both the 20x5 plot and the 15x15 plot and costs 300. The total cost is 500, which is minimal.






    首先按高度递减,否则宽度递增来排序,这样可以去掉被某一个阵地包含的无用阵地

    这样处理完之后,可以发现剩下的阵地有一个特点,就是高度递减,宽度递增,

    于是不难想象,最有的方法是选连续的阵地,所以dp方程很好写:

    然后这题的斜率项是一个正数,貌似图跟一般的不一样啊。。。

    但是靠j优于k的式子搞就完事了





     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int N=100010;
     5 inline ll read();
     6 inline void write(ll x);
     7 inline void writeln(ll x);
     8 
     9 int n,cnt=0;
    10 int q[N],head=1,tail=0;
    11 ll dp[N];
    12 struct aa{
    13     ll x,y;
    14 } field[N],work[N];
    15 inline bool operator<(const aa &a,const aa &b)
    16 {
    17     if(a.x!=b.x) return a.x<b.x;
    18     return a.y<b.y;
    19 }
    20 #define Y(i) (dp[(i)])
    21 #define X(i) (-work[(i)+1].y)
    22 #define Slope(i,j) 1.0*(Y(i)-Y(j))/(X(i)-X(j))
    23 #define calc(i,j) (dp[(j)]+work[i].x*work[j+1].y)
    24 
    25 inline ll read()
    26 {
    27     ll s=0;
    28     bool flag=false;
    29     char ch=getchar();
    30     for(;ch<'0'||ch>'9';ch=getchar()) if(ch=='-') flag=true;
    31     for(;'0'<=ch&&ch<='9';ch=getchar()) s=(s<<3)+(s<<1)+(ch^48);
    32     if(flag) return -s;
    33     return s;
    34 }
    35 inline void write(ll x)
    36 {
    37     if(!x)
    38     {
    39         putchar('0'),putchar(' ');
    40         return ;
    41     }
    42     if(x<0) putchar('-'),x=-x;
    43     char ch[20];
    44     int tot=0;
    45     while(x) ch[++tot]=x%10,x/=10;
    46     for(int i=tot;i;i--) putchar(ch[i]^48);
    47     putchar(' ');
    48 }
    49 inline void writeln(ll x)
    50 {
    51     write(x);
    52     putchar('
    ');
    53 }
    54 
    55 int main()
    56 {
    57     n=read();
    58     for(int i=1;i<=n;i++) field[i].x=read(),field[i].y=read();
    59     sort(field+1,field+n+1);
    60     for(int i=1;i<=n;i++)
    61     {
    62         while(cnt&&field[i].y>=work[cnt].y) cnt--;
    63         work[++cnt]=field[i];
    64     }
    65     n=cnt;
    66     memset(dp,0x3f,sizeof(dp));
    67     dp[0]=0;
    68     q[++tail]=0;
    69     for(int i=1;i<=n;i++)
    70     {
    71         for(;head<tail&&Slope(q[head],q[head+1])<=work[i].x;head++);
    72         dp[i]=calc(i,q[head]);
    73         for(;head<tail&&Slope(q[tail-1],q[tail])>=Slope(q[tail],i);tail--);
    74         q[++tail]=i;
    75     }
    76     writeln(dp[n]);
    77     return 0;
    78 }
  • 相关阅读:
    前后端数据处理+数据展示分页
    数据库表关系:多对多的三中方式
    MTV与MVC模式
    F与Q查询
    ORM表单操作
    IIS 7 应用程序池自动回收关闭的解决方案
    ASP.NET MVC 使用带有短横线的html Attributes
    能加载文件或程序集“XXX”或它的某一个依赖项,系统找不到指定的文件
    调试MVC项目,不关闭 IIS EXPRESS
    已有打开的与此 Command 相关联的 DataReader,必须首先将它关闭
  • 原文地址:https://www.cnblogs.com/zhangbuang/p/10617204.html
Copyright © 2011-2022 走看看