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 }

 

 

 

 

posted @ 2012-08-16 22:32  _雨  阅读(239)  评论(0编辑  收藏  举报