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 }

     

     

  • 相关阅读:
    Best Time to Buy and Sell Stock III
    Valid Palindrome
    Longest Substring Without Repeating Characters
    Copy List with Random Pointer
    Add Two Numbers
    Recover Binary Search Tree
    Anagrams
    ZigZag Conversion
    Merge k Sorted Lists
    Distinct Subsequences
  • 原文地址:https://www.cnblogs.com/shangyu/p/2643180.html
Copyright © 2011-2022 走看看