• [Luogu 2816]宋荣子搭积木


    Description

    saruka非常喜欢搭积木,他一共有n块积木。而且saruka的积木很特殊,只能一块块的竖着摞,可以摞很多列。说过saruka的是特殊的积木了,这些积木都非常智能,第i块积木有一个情绪值xi,当摞在这块积木上的积木总数超过xi时,这块积木就会很不高兴,发誓以后不会再和saruka一起玩耍了。saruka这么爱玩积木,肯定不会让积木不高兴的,但是saruka又希望每块积木都被用上,并且摞的积木列数最少。你能来帮帮saruka嘛?

    Input

    第一行一个整数n,含义如题目描述所示

    第二行有n个数xi,含义如题目描述所示

    Output

    输出一个数字,代表最小的积木列数

    Sample Input

    3
    0 0 10

    Sample Output

    2

    HINT

    1 <= n <= 5000

    xi <= n

    题解

    题解都是从小到大排序...然后一个一个丢进去....

    但是考场上想到的是二分...也过了...

    我们将$x$排序从大到小,二分答案,将这$n$个数:第$i$个数放在$i$ $mod$ $mid$的堆上。边遍历边判断是否可行。

    感觉应该也没问题...也不会证(大概就是尽可能地利用了$x$吧...)

     1 //It is made by Awson on 2017.10.5
     2 #include <map>
     3 #include <set>
     4 #include <cmath>
     5 #include <ctime>
     6 #include <queue>
     7 #include <stack>
     8 #include <vector>
     9 #include <cstdio>
    10 #include <string>
    11 #include <cstdlib>
    12 #include <cstring>
    13 #include <iostream>
    14 #include <algorithm>
    15 #define LL long long
    16 #define Max(a, b) ((a) > (b) ? (a) : (b))
    17 #define Min(a, b) ((a) < (b) ? (a) : (b))
    18 #define sqr(x) ((x)*(x))
    19 using namespace std;
    20 const int N = 5000;
    21 void read(int &x) {
    22   char ch; bool flag = 0;
    23   for (ch = getchar(); !isdigit(ch) && ((flag |= (ch == '-')) || 1); ch = getchar());
    24   for (x = 0; isdigit(ch); x = (x<<1)+(x<<3)+ch-48, ch = getchar());
    25   x *= 1-2*flag;
    26 }
    27 
    28 int n, a[N+5];
    29 bool comp(const int &a, const int &b) {
    30   return a > b;
    31 }
    32 
    33 bool judge(int mid) {
    34   int rest[N+5];
    35   for (int i = 1; i <= mid; i++)
    36     rest[i] = a[i];
    37   for (int i = mid+1; i <= n; i++) {
    38     int t = i%mid;
    39     if (!t) t = mid;
    40     rest[t] = Min(rest[t]-1, a[i]);
    41     if (rest[t] < 0) return false;
    42   }
    43   return true;
    44 }
    45 
    46 void work() {
    47   read(n);
    48   for (int i = 1; i <= n; i++) read(a[i]);
    49   sort(a+1, a+n+1, comp);
    50   int l = 1, r = n, ans = n;
    51   while (l <= r) {
    52     int mid = (l+r)>>1;
    53     if (judge(mid)) ans = mid, r = mid-1;
    54     else l = mid+1;
    55   }
    56   printf("%d
    ", ans);
    57 }
    58 int main() {
    59   work();
    60   return 0;
    61 }
  • 相关阅读:
    Security 前端页面配置
    使用HttpSession获取用户信息
    开启使用Tonken记住我功能
    基于注解的方式发送和订阅消费消息
    通过Security提供的SecurityContextHolder获取登录用户信息
    RabbitMQ 基于API的方式发送和消费消息
    TypeScript declare Object Array Interface methods All In One
    js get Set the first item All In One
    macOS run VSCode from terminal All In One
    在线 Java 语言编程 All In One
  • 原文地址:https://www.cnblogs.com/NaVi-Awson/p/7629890.html
Copyright © 2020-2023  润新知