zoukankan      html  css  js  c++  java
  • bzoj2600 [Ioi2011]ricehub

    Description

    乡间有一条笔直而长的路称为“米道”。沿着这条米道上 R 块稻田,每块稻田的坐标均为一个 1 到 L 之间(含 1 和 L)的整数。这些稻田按照坐标以不减的顺序给出,即对于 0 ≤ i <R,稻田 i 的坐标 X[i]满足 1 ≤ X[0] ≤ ... ≤ X[R-1] ≤ L。 

    注意:可能有多块稻田位于同一个坐标上。 

    我们计划建造一个米仓用于储存尽可能多的稻米。和稻田一样,米仓将建在米道上,其坐标也是一个 1 到 L 之间的整数(含 1 和 L)。这个米仓可以建在满足上述条件的任一个位置上,包括那些原来已有一个或多个稻田存在的位置。 

    在收获季节,每一块稻田刚好出产一滿货车的稻米。为了将这些稻米运到米仓,需要雇用一位货车司机来运米。司机的收费是每一满货车运送一个单位的距离收取 1 元。換言之,将稻米从特定的稻田运到米仓的费用在数值上等于稻田坐标与米仓坐标之差的绝对值。 不幸的是,今年预算有限,我们至多只能花费 B 元运费。你的任务是要帮我们找出一个建造米仓的位置,可以收集到尽可能多的稻米。 

    Input

    第一行 三个整数 R L B
    接下来R行 每行一个整数 表示X[i]

    Output

    一个整数 最多稻米数

    Sample Input

    5 20 6
    1
    2
    10
    12
    14

    Sample Output

    3
    HINT
    1 ≤ R ≤ 100,000
    1 ≤ L ≤ 1,000,000,000
    0 ≤ B ≤ 2,000,000,000,000,000

    正解:二分答案。

    $IOI$第一题,还是道水题。。

    考虑二分答案,二分到$mid$时分奇偶讨论一下$mid$个点的中点到这些点的距离,复杂度为$O(mid)$然后我们从前往后推,发现推到下一个中点时只需改变左右两个端点到中点的距离就行了,所以改变中点的复杂度是$O(1)$的,那么每次$check$的复杂度就是$O(n)$的。于是我们就可以在$O(nlogn)$的时间内解决这个问题了。

     1 //It is made by wfj_2048~
     2 #include <algorithm>
     3 #include <iostream>
     4 #include <cstring>
     5 #include <cstdlib>
     6 #include <cstdio>
     7 #include <vector>
     8 #include <cmath>
     9 #include <queue>
    10 #include <stack>
    11 #include <map>
    12 #include <set>
    13 #define inf (1<<30)
    14 #define N (500010)
    15 #define il inline
    16 #define RG register
    17 #define ll long long
    18 #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
    19 
    20 using namespace std;
    21 
    22 ll a[N],n,l,b,ans;
    23 
    24 il ll gi(){
    25     RG ll x=0,q=1; RG char ch=getchar();
    26     while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
    27     if (ch=='-') q=-1,ch=getchar();
    28     while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar();
    29     return q*x;
    30 }
    31 
    32 il ll check(RG ll key){
    33     RG double tot=0;
    34     if (key&1){
    35     RG ll len=key>>1,p=len+1;
    36     for (RG ll i=1;i<=key;++i) tot+=abs(a[p]-a[i]);
    37     if (tot<=b) return 1;
    38     for (++p;p+len<=n;++p){
    39         tot-=abs(a[p-1]-a[p-len-1]);
    40         tot+=abs(a[p]-a[p+len]);
    41         if (tot<=b) return 1;
    42     }
    43     } else{
    44     RG ll len=key>>1,p=len;
    45     for (RG ll i=1;i<=key;++i) tot+=abs(a[p]-a[i]);
    46     if (tot<=b) return 1;
    47     for (++p;p+len<=n;++p){
    48         tot-=abs(a[p]-a[p-len]);
    49         tot+=abs(a[p]-a[p+len]);
    50         if (tot<=b) return 1;
    51     }
    52     }
    53     return 0;
    54 }
    55 
    56 il void work(){
    57     n=gi(),l=gi(),b=gi();
    58     for (RG ll i=1;i<=n;++i) a[i]=gi();
    59     RG ll l=0,r=n,mid;
    60     while (l<=r){
    61     mid=(l+r)>>1;
    62     if (check(mid)) ans=mid,l=mid+1;
    63     else r=mid-1;
    64     }
    65     printf("%lld
    ",ans); return;
    66 }
    67 
    68 int main(){
    69     File("ricehub");
    70     work();
    71     return 0;
    72 }
  • 相关阅读:
    POJ3159 Candies —— 差分约束 spfa
    POJ1511 Invitation Cards —— 最短路spfa
    POJ1860 Currency Exchange —— spfa求正环
    POJ3259 Wormholes —— spfa求负环
    POJ3660 Cow Contest —— Floyd 传递闭包
    POJ3268 Silver Cow Party —— 最短路
    POJ1797 Heavy Transportation —— 最短路变形
    POJ2253 Frogger —— 最短路变形
    POJ1759 Garland —— 二分
    POJ3685 Matrix —— 二分
  • 原文地址:https://www.cnblogs.com/wfj2048/p/6985921.html
Copyright © 2011-2022 走看看