zoukankan      html  css  js  c++  java
  • CSU 1364 Interview RMQ

    题意:

      瑶瑶有一家有一家公司,最近他想招m个人。因为他的公司是如此的出名,所以有n个人来参加面试。然而,瑶瑶是如此忙,以至于没有时间来亲自面试他们。所以他准备选择m场面试来测试他们。

      瑶瑶决定这样来安排面试。首先,他把这些面试者按照来到的顺序排成一队。然后,他把这个队列切成m段。每段的长度是[n/m](向下取整),这意味着他将忽略掉剩下的人。然后,他将选择每一段里面最好的那个人。

      瑶瑶的想法看起来很有趣,但是他遇到了另外的问题。他把每个人的能力赋了一个值。值越大的越好。他希望员工足够的好,这样,他们的和可以达到他的目标k(严格大于)。另一方面,因为现在高昂的工资,他希望员工的数量尽可能少。

      你能帮他找出最小的m吗?

    思路:

      Sparse Table + 枚举区间长度。

      枚举区间个数会TLE,不懂为什么,代码也有点没看懂。

    代码:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <cmath>
     5 
     6 using namespace std;
     7 
     8 const int MAXN = (int)2e5+5;
     9 
    10 int ST[21][MAXN]; //Sparse Table
    11 int hight[MAXN];
    12 int n, k;
    13 
    14 inline int topBit(int x) {
    15     return (int) (log((double)x)/log(2.0));
    16 }
    17 
    18 inline int Query(int L, int R) {
    19     int h = hight[R-L];
    20     if ((R-L) < (1<<h)) h -= 1;
    21     return max(ST[h][L], ST[h][R-(1<<h)]);
    22 }
    23 
    24 int main() {
    25     #ifdef Phantom01
    26         freopen("CSU1364.in", "r", stdin);
    27     #endif // Phantom01
    28 
    29     memset(hight, 0, sizeof(hight));
    30     for (int i = 1; i < MAXN; i++) //比他左位移一位的数高一
    31         hight[i] = hight[i>>1] + 1;
    32 
    33     while (scanf("%d %d", &n, &k)!=EOF) {
    34         if (-1==n && -1==k) break;
    35 
    36         for (int i = 0; i < n; i++)
    37             scanf("%d", &ST[0][i]); //最下面一层就是原始数据
    38 
    39         int h = hight[n];
    40         for (int i = 1; i <= h; i++) {
    41             for (int j = 0; j < n; j++) {
    42                 if ((j+(1<<(i-1))) < n)
    43                     ST[i][j] = max(ST[i-1][j], ST[i-1][j+(1<<(i-1))]);
    44                 else
    45                     ST[i][j] = ST[i-1][j];
    46             }
    47         }
    48         int ans = -1;
    49         for (int i = n; i > 0; i--) {
    50             int m = n/i;
    51             int tmp = 0;
    52             for (int j = 0; j < m; j++) {
    53                 tmp += Query(j*i, (j+1)*i);
    54                 if (tmp>k) {
    55                     ans = j+1; //不知道这里为啥是j+1而不是 m
    56                     break;
    57                 }
    58             }
    59             if (tmp > k)
    60                 break;
    61         }
    62         printf("%d
    ", ans);
    63     }
    64 
    65     return 0;
    66 }
    View Code

     -------------------------

    PS: 后来看到一个代码,直接二分答案即可,复杂度也是n*log(n)的,但是编程复杂度没这么大。

     1 #include <cstdio>
     2  
     3 int a[200010], n;
     4  
     5 bool Can(int m, int k)
     6 {
     7     int i, j, t, sum, MAX;
     8     t = n / m;
     9     for (i = j = sum= 0; i < m; i++)
    10     {
    11         MAX = -1;
    12         for (j = 0; j < t; j++)
    13             if (MAX < a[i*t+j]) MAX = a[i*t+j];
    14         sum += MAX;
    15         if (sum > k) return true;
    16     }
    17     return sum > k;
    18 }
    19  
    20 int main()
    21 {
    22     int k, m, up, down, i, sum;
    23     //freopen("in", "r", stdin);
    24     while (scanf("%d%d", &n, &k), n >= 0 && k >= 0)
    25     {
    26         for (i = sum = 0; i < n; i++)
    27         {
    28             scanf("%d", a + i);
    29             sum += a[i];
    30         }
    31         if (sum <= k) puts("-1");
    32         else {
    33             down = 1; up = n;
    34             while (down < up)
    35             {
    36                 m = (up + down) / 2;
    37                 if (Can(m, k)) up = m;
    38                 else down = m + 1;
    39             }
    40             printf("%d
    ", up);
    41         }
    42     }
    43     return 0;
    44 }
    View Code
  • 相关阅读:
    go语言之行--简介与环境搭建
    Django Rest Framework源码剖析(八)-----视图与路由
    基于TLS证书手动部署kubernetes集群(下)
    多线程编程
    Java IO流
    java异常处理
    字符串处理(二)
    字符串处理(一)
    正则表达式(应用)
    集合相关知识
  • 原文地址:https://www.cnblogs.com/Phantom01/p/3657819.html
Copyright © 2011-2022 走看看