zoukankan      html  css  js  c++  java
  • hdu4377Sub Sequence(多校八 )(找规律)

    http://acm.hdu.edu.cn/showproblem.php?pid=4377

    写了一下午也没找出规律 还剩十几分钟的时候CZ看出了规律 这时候再找正确的字典序已经晚了,,

    官方解题报告:

    其实这是个挺有趣的题,你需要构造一个 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 也不容易,这就要克服各种逻辑上的问题,形成良好的思维习惯,对于解题来说也是十分重要的。

     

    把这N个数放在sqrt(N)块中 要保证大数尽量在后面 比如分成5块 就尽量让最后几块都填满 在保证前几块至少有一个的情况下

    10  1 ,2, 6 5 4 3, 10 9 8 7,

    11  1, 3 2, 7 6 5 4, 11 10 9 8,

    12  1, 4 3 2, 8 7 6 5, 12 11 10 9.

    View Code
     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <stdlib.h>
     4 #include<math.h>
     5 int num[10001];
     6 int main()
     7 {
     8     int t,a,i,j,k,y,d,kk,yy;
     9     scanf("%d",&t);
    10     while(t--)
    11     {
    12         d = 0;
    13         kk = 0;
    14         scanf("%d",&a);
    15         int x = sqrt(a);
    16         if(x*x==a)
    17         k = x;
    18         else
    19         k = x+1;
    20         d = k;
    21         while(a)//求每个区域放几个数
    22         {
    23             if(a-(d-1)>=k)
    24             {
    25                 num[d--] = k;
    26                 a-=k;
    27             }
    28             else
    29             if(a>d)
    30             {
    31                 num[d] = a-d+1;
    32                 int dd = a-d+1;
    33                 d--;
    34                 a-= dd;
    35             }
    36             else
    37             {
    38                 num[d--] = 1;
    39                 a--;
    40             }
    41         }
    42         y = 0;
    43         for(i =1 ; i <= k ; i++)
    44         {
    45             y+=num[i];
    46             yy = y;
    47             for(j = num[i] ; j >= 1 ; j--)
    48             {
    49                 if(kk!=0)
    50                 printf(" ");
    51                 printf("%d",y);
    52                 y--;
    53                 kk++;
    54             }
    55             y = yy;
    56         }
    57         printf("\n");
    58     }
    59     return 0;
    60 }

     

     

  • 相关阅读:
    利用dockerfile定制镜像
    发布Docker 镜像到dockerhub
    Docker 停止容器
    133. Clone Graph
    132. Palindrome Partitioning II
    131. Palindrome Partitioning
    130. Surrounded Regions
    129. Sum Root to Leaf Numbers
    128. Longest Consecutive Sequence
    127. Word Ladder
  • 原文地址:https://www.cnblogs.com/shangyu/p/2643180.html
Copyright © 2011-2022 走看看