单调栈【小记】

第一次接触单调栈是暑假的时候,那时做到了了 HDU上的一题 : Largest Rectangle in a Histogram

后来在范总的帮助下敲掉了。

今天决定重新坐下这类题,目的是完善下代码风格和熟悉下。


题目都是蛮简单的,核心算法就是用单调栈处理出第i个点左右最长可以延伸到的位置(记做 : L[i] 和 R[i])。


挂了三道POJ题目 :

 1  Terrible Sets    :  (题意有点坑而已,理解后会发现和HDU上那题是一样的)

 2  Feel Good         : (首先O(n)预处理出任意区间和,然后注意下会超int需要用__int64来保存区间和和最后的答案)

 3  Sticks Problem: (单调栈预处理后,我是用O(n^2)寻找最后的答案的,如果从R[i] 的最右端找过来,虽然看似O(n^2),但是如果符合要求直接break的话还是可以过的)



最后贴一个单调栈预处理的代码 :

 

void init()
{
      sta[0] = 0; cnt = 0;
      for (int i = 1;i <= n;i++)
      {
            if (a[i] >= sta[cnt])
            {
                  sta[++cnt] = a[i];
                  tot[cnt] = i;
            }
            else
            {
                  while (a[i] < sta[cnt])
                  {
                        R[tot[cnt]] = i - 1;
                        cnt--;
                  }
                  sta[++cnt] = a[i];
                  tot[cnt] = i;
            }
      }
      for (int i = 1;i <= cnt;i++)R[tot[i]] = n;
      sta[0] = 0; cnt = 0;
      for (int i = n;i >= 1;i--)
      {
            if (a[i] >= sta[cnt])
            {
                  sta[++cnt] = a[i];
                  tot[cnt] = i;
            }
            else
            {
                  while (a[i] < sta[cnt])
                  {
                        L[tot[cnt]] = i + 1;
                        cnt--;
                  }
                  sta[++cnt] = a[i];
                  tot[cnt] = i;
            }
      }
      for (int i = 1;i <= cnt;i++)L[tot[i]] = 1;
}

 

转载于:https://www.cnblogs.com/cnwsycf/p/3335356.html

你可能感兴趣的:(单调栈【小记】)