谁看的最多

今天想到了昨天看到一道acm题目,难度入门级别。“谁看的最多”,题目大概是这样的:一队列的人3 2 1 6 4 5,数值的大小表示该人的高度。每个人只能看到前面比他高的人,如1可以看见2、3。但是,如果有人B比他高,那么他就不能看到这那个B之前比B低的人了。如5,因为6比他高,他只能看到6,但看不到6之前的人(如果之前有7、8之类比6高的,5也可以看到)。而4比5低也看不到。

题目想了个大概就没有想了,又是卡在里动态规划的状态里。F(i)表示第i个人看到的人数。如果他前一个人比i低,则i看到的最多只有一个了,就是i-1。如果他比前一个高,则看到的就是前i-1个人第一个比他高的人看的人数加一。如果可以快速找前面i-1的第一个比i高,就可以利用动态规划的方法了。通过一个数组记录i前面的第一个比i高的位置,这样就可以快速找出。

状态转移方程:F(i)=若i比i-1高,为F(j)+1,j为前面的第一比i高的;否则为1(i>0。i=0,看到就为0个)

挫挫代码:

 1 int func10(int a[], int n)
 2 {
 3     int i,j;
 4     int maxsee;
 5     int *see,*tall;
 6 
 7     if (n<0)
 8     {
 9         return -1;
10     }
11     see = (int*)malloc(n*sizeof(int));
12     tall = (int*)malloc(n*sizeof(int));
13 
14     maxsee = see[0] = 0;
15     tall[0] = -1; //之前未有比其高的
16 
17     for (i=1; i<n; i++)
18     {
19         if (a[i] > a[i-1])
20         {
21             for (j=tall[i-1]; j>0; )
22             {
23                 if (a[i]<=a[j])
24                 {
25                     break;
26                 }
27                 j=tall[j];
28             }
29             if (j==-1)
30             {
31                 see[i] = 0;
32                 tall[i] = -1;
33             }
34             else
35             {
36                 see[i] = see[j] +1;
37                 tall[i] = j;
38             }
39         }
40         else  //a[i]<=a[i-1]
41         {
42             see[i] = see[i-1]+1;
43             tall[i] = i-1;
44         }
45 
46         maxsee = maxsee<see[i] ? see[i]  : maxsee;
47     }
48 
49     free(see);
50     free(tall);
51 
52     return maxsee;
53 
54 }

又一题。

复习还是不给力。。。继续。。

毕。

 修订2013-4-18 :

在不断的被虐之后,发现其是这个算法的题目是ACM中一个犀利的数据结构:单调栈的应用(参考博客中的另一篇文章:单调栈:柱形统计图中最大面积(POJ 2559)其实此问题的解决就是单调栈的思想,通过记录的一些信息模拟单调栈。其算法复杂度和单调栈是一致的。

posted @ 2013-03-22 21:11  legendmaner  阅读(501)  评论(0编辑  收藏  举报