zoukankan      html  css  js  c++  java
  • 【ZOJ4062】Plants vs. Zombies(二分)

    题意:有n个植物排成一排,标号为1-n,每株植物有自己的生长速度ai,每对植物浇一次水,该株植物就长高ai,

    现在机器人从第0个格子出发,每次走一步,不能停留,每一步浇一次水,总共可以走m步,问最矮的植物最高是多少。

    n<=1e6,sigma n<=1e7,0<=m<=1e12,1<=a[i]<=1e5

    思路:7Y……你不死谁死

    显然最小值最大可以二分,二分答案,最优的策略一定是从左到右依次左右横跳,直到当前格子不小于二分的值

    一个致命的细节:最后一个如果在倒数第二个左右横跳的时候已经够了则不需要再走到了

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<string>
     4 #include<cmath>
     5 #include<iostream>
     6 #include<algorithm>
     7 #include<map>
     8 #include<set>
     9 #include<queue>
    10 #include<vector>
    11 using namespace std;
    12 typedef long long ll;
    13 typedef unsigned int uint;
    14 typedef unsigned long long ull;
    15 typedef pair<int,int> PII;
    16 typedef vector<int> VI;
    17 #define fi first
    18 #define se second 
    19 #define MP make_pair
    20 #define N      110000
    21 #define M      51
    22 #define MOD 1000000007
    23 #define eps 1e-8 
    24 #define pi     acos(-1)
    25 #define oo     1010000000
    26 
    27 ll a[N],b[N],m;
    28 int n;
    29 
    30 int isok(ll k)
    31 {
    32     for(int i=1;i<=n+1;i++) b[i]=0;
    33      ll t=0;
    34     for(int i=1;i<=n;i++)
    35     {
    36         if(i==n&&b[n]>=k) continue;
    37         t++;
    38         if(t>m) return 0;
    39         b[i]+=a[i];
    40         if(b[i]<k)
    41         {    
    42             ll tmp=(k-b[i])/a[i];
    43             if(tmp*a[i]+b[i]<k) tmp++;
    44             t=t+tmp*2;
    45             if(t>m)    return 0;
    46             b[i]+=a[i]*tmp;
    47             b[i+1]+=a[i+1]*tmp;
    48         }
    49     }
    50     if(t>m) return 0;
    51     return 1;
    52 }
    53 
    54 int main()
    55 { 
    56      int cas;
    57      scanf("%d",&cas);
    58      for(int v=1;v<=cas;v++) 
    59      {
    60         scanf("%d%lld",&n,&m);
    61         for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
    62         ll l=1;
    63         ll r=1e17;
    64         ll last=0;
    65         while(l<=r)
    66         {
    67             ll mid=(l+r)/2;
    68             if(isok(mid)){last=mid; l=mid+1;}
    69              else r=mid-1;
    70         }
    71         printf("%lld
    ",last); 
    72     }
    73     return 0;
    74 }
    75     
  • 相关阅读:
    mplayer命令行模式下的使用方法
    CentOS安装wireshark
    CentOS查看系统信息
    测试理论1
    单例模式
    接口测试
    rabbitmq
    redis数据库
    时间模块
    charles抓取数据
  • 原文地址:https://www.cnblogs.com/myx12345/p/10045609.html
Copyright © 2011-2022 走看看