1D1D动态规划 O(nlogn) 二分栈优化

虽然我所写的在《1D1D动态规划优化初步》已经讲的很详细了,但是因为最近又考到了一回,我还是写到这里来。

1D1D 方程,即所谓 f[i] = max or min {f[i '] + x[i '][i]} ,显然裸做是平方的复杂度。

首先的条件就是决策的单调性。这一点不多讲,若不能数学证明则打表或对拍证明。

然后就是决策集合的单调,这决定了可以二分,即将复杂度从 O(n * n) 降到 O(nlogn) 的关键。其实这也决定了可以用一种常数性的优化,即从上一个决策开始枚举状态转移,不过相较于 nlogn 的复杂度还是太慢,所以不多赘述。

首先将最初是决策加入决策集合(用一个队列表示),范围适用于全体状态。

接着用集合中的状态更新绝对可以更新的状态。接着,用当前所得到的状态去更新决策集合中的状态。因为决策集合是单调的,所以可以二分更新。

接着重复以上两步,直到所有的状态都被更新完。

总状态数为 n,每次二分的复杂度不超过 O(logn),所以总复杂度为 O(nlogn)。

模板 Code:

     push(1, n, 0);
     for (int i = 1; i <= n; i ++)
     {
          f[i] = p(pop_head(), i);
          while (ll < rr)
          {
               int l = x[rr], r = y[rr], j = z[rr];
               if (p(i, l) < p(j, l)) {pop_tail(); continue;}
               if (p(i, r) > p(j, r)) break;
               while (l < r)
               {
                    int m = (l + r) >> 1;
                    p(i, m) < p(j, m) ? r = m : l = m + 1;
               }
               push(l, y[rr], i); break;
          }
          if (ll >= rr) push(i + 1, n, i);
     }


你可能感兴趣的:(1D1D动态规划 O(nlogn) 二分栈优化)