zoukankan      html  css  js  c++  java
  • hdu 3486 RMQ

    题意:有n个人排队应聘,每个人有一个能力值,然后老板要把这些人分成m段,如果不能整除多出来就后面的人就不要了,然后从这m段里面选择每段的最大能力值加起来看是否能够大于老板需要的目标k,因为薪资问题,尽可能少录取人,所以找出满足条件的最小的m。

    输入时找出所有能力值的最大值max,则分组最少为k/max(缩短时间,否则会TLE);然后枚举之后的分组,在每个分组内找最大值(RMQ),sum+=RMQ(L,R);当碰到第一个满足条件的分组时(sum>k),就可以跳出循环,直接输出答案了。

    RMQ一般用于求区间最值问题,但是也可以求类似区间gcd这种,不涉及到更新用RMQ会更快一点,否则还是用线段树。

     1 #include<iostream>
     2 #include<stdio.h>
     3 #include<math.h>
     4 #include<algorithm>
     5 #define LL long long
     6 
     7 using namespace  std;
     8 
     9 const int MAX_N = 200005;
    10 LL k,n;
    11 int num[MAX_N];
    12 int dp[MAX_N][20];
    13 
    14 void rmq_init()
    15 {
    16     for(int i = 0; i < n; i++)
    17         dp[i][0] = num[i];
    18     for(int j = 1; (1<<j) <= n; j++)
    19     {
    20         for(int i = 0; i+(1<<j)-1 < n; i++)
    21         {
    22             dp[i][j] = max(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
    23         }
    24     }
    25 }
    26 
    27 int rmq(int l,int r)
    28 {
    29     int k = 0;
    30     while(1<<(k+1)<=(r-l+1))
    31         k++;
    32     return max(dp[l][k],dp[r-(1<<k)+1][k]);
    33 }
    34 int main()
    35 {
    36     while(cin>>n>>k,n>0 || k>=0)
    37     {
    38         int maxx = 0,sum = 0;
    39         for(int i = 0; i < n; i++)
    40         {
    41             cin>>num[i];
    42             if(num[i]>maxx)
    43                 maxx = num[i];
    44             sum+=num[i];
    45         }
    46         if(sum<k)
    47         {
    48             cout<<-1<<endl;
    49             continue;
    50         }
    51         rmq_init();
    52         int zu = k / maxx;
    53         int peo,new_sum;
    54         if(zu==0)
    55             zu=1;
    56         for(;zu<=n;zu++)
    57         {
    58             peo = n/zu;
    59             new_sum = 0;
    60             for(int i = 1; i <= zu; i++)
    61             {
    62                 new_sum+=rmq((i-1)*peo,i*peo-1);
    63             }
    64             if(new_sum>k)
    65             {
    66                 break;
    67             }
    68         }
    69         cout<<zu<<endl;
    70     }
    71     return 0;
    72 }
  • 相关阅读:
    3个同一行div的摆放div
    Android 项目开发
    iOS 8
    iOS 8
    __FILE__ 与 $_SERVER['SCRIPT_FILENAME']的区别
    高德百度坐标系转换方法
    高德百度坐标系转换方法
    在iOS开发中使用icon font的方法
    在iOS开发中使用icon font的方法
    UIView的setNeedsLayout, layoutIfNeeded 和 layoutSubviews 方法之间的关系解释
  • 原文地址:https://www.cnblogs.com/Xycdada/p/7422109.html
Copyright © 2011-2022 走看看