文章目录

HDU 7541 LIS 做题笔记

发布于

题意

给定长度为 $n$ 的排列 $a$,删除 $a_i$ 的代价是 $b_i$。

现在希望删除一些 $a_i$,使得删完后 $a$ 的最长上升子序列长度不超过 $k$,最小化被删除元素的代价和。

对 $k \in \left[1, n\right]$ 分别求出答案。

题解

根据 Dilworth 定理,LIS 长度为 $k$,代表可以用 $k$ 个下降子序列覆盖全部。

因此对于每个 $k$,我们要求出用 $k$ 条下降子序列最多能覆盖多大的权值。

因此,SSP 的每次增广过后,都统计一次答案即可。

时间复杂度 $O\left(n^4\right)$,如果是原始对偶的话可以做到 $O\left(n^3\right)$

代码

int STRUGGLING([[maybe_unused]] unsigned long long int TEST_NUMBER) {
   tp n; cin >> n;
   tp s = 0;
   tp t = 2 * n + 1;
   vector<vector<tuple<tp, tp, tp>>> e(t + 1);
   vetp a(n + 1, 0);
   vetp b(n + 1, 0);
   for (tp i = 1; i <= n; ++i) cin >> a[i];
   for (tp i = 1; i <= n; ++i) cin >> b[i];
   for (tp i = 1; i <= n; ++i) {
      e[s].emplace_back(2 * i - 1, 1, 0);
      e[2 * i].emplace_back(t, 1, 0);
      e[2 * i - 1].emplace_back(2 * i, 1, -b[i]);
      for (tp j = i + 1; j <= n; ++j) {
         if (a[i] > a[j]) e[2 * i].emplace_back(2 * j - 1, 1, 0);
      }
   }
   lib::MCMF(e, s, t, accumulate(1 + FULL(b), ZERO));
   cout << '\n';
   return 0;
}

暂无评论

发表评论