• HDU 4377 Sub Sequence [构造]


      用1~N构造一个序列,使max(最长上升子序列,最长下降子序列)最小,并且字典序最小。

      最近做的构造题好多,这种1~N的序列大多是sqrt(n)的构造。。

      官方题解:

      其实这是个挺有趣的题,你需要构造一个 1..N 的排列,使得其最长上升序列的长度和最长下降序列的长度的最大值最小。应该比较容易能够想到这个答案是 sqrt(N) 级别的,这个结论的证明可以参考吴文虎的那本组合数学 p21 。
      当然这还没有结束,怎么找字典序最小的那个解呢?先看看完全平方数吧,对于 4 ,我们有 2 1 4 3 ,对于 9 ,我们有 3 2 1 6 5 4 9 8 7 。嗯,完全平方数的规律还是好找的,那么 5 呢?不就是加一个数么,1 3 2 5 4 ,如果你觉得这是答案,那你就大错特错了,答案是 1 2 5 4 3 。同样,对于 10 ,答案是 1 2 6 5 4 3 10 9 8 7 。
      于是我们就可以构造程序,每次以 ceil(sqrt(N)) 为一组,尽量把大的数安排到后面的组中,同时要注意,一定要分出 ceil(sqrt(N)) 组,能让较小的 1 2 这样的数能够排在前面。
      最后,这题并不难,但是做到 1Y 也不容易,这就要克服各种逻辑上的问题,形成良好的思维习惯,对于解题来说也是十分重要的。

      

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <math.h>
     4 int cas, n;
     5 int main(){
     6     scanf("%d", &cas);
     7     while (cas--) {
     8         scanf("%d", &n);
     9         int k = sqrt(n+1e-9);
    10         if (k * k == n) {
    11             for (int i = 0; i < n; i++)
    12                 printf("%d%c", i/k*k + k - i%k, i==n-1?'\n':' ');
    13             continue;
    14         }
    15         k++;
    16         int d = n % k;
    17         if (d == 0) d = k;
    18         if ((n-d)/k + 2 <= k)
    19             for (int i = 0; i < d; i++) printf("%d%c", i==0?1:d-i+1, i==n-1?'\n':' ');
    20         else
    21             for (int i = 0; i < d; i++) printf("%d%c", d - i, i==n-1?'\n':' ');
    22         for (int i = d; i < n; i++)
    23             printf("%d%c", d + (i-d)/k*k - (i-d)%k + k, i==n-1?'\n':' ');
    24     }
    25     return 0;
    26 }
  • 相关阅读:
    [LeetCode] 981. Time Based Key-Value Store
    [LeetCode] 97. Interleaving String
    [LeetCode] 953. Verifying an Alien Dictionary
    代价敏感的学习方法
    深度学习中Dropout原理解析
    梯度下降法的三种形式BGD、SGD以及MBGD
    吉布斯采样(Gibbs Sampling)简介(转)
    Java中next()和hasNext() ? nextLine()和hasNextLine()?区别详解
    红黑树介绍及旋转详解
    Pycharm中实现openCV安装好后简单测试
  • 原文地址:https://www.cnblogs.com/swm8023/p/2725207.html
Copyright © 2020-2023  润新知