bzoj 1563 [NOI2009]詩人小G 決策單調性+dp
阿新 • • 發佈:2018-08-15
ref bit std online mes pac c++ () include
題面
題目傳送門
解法
可以得到一個顯然的dp方程
$\(f_i=min(f_j+(s_i-s_j+i-j-1-L)^p)\)
不妨把後面的東西看成\(w(j,i)\)
所以就變成\(f_i=min(f_j+w(j,i))\)
可以發現,這個式子滿足四邊形不等式
1D1D的四邊形不等式可以直接通過決策單調性來優化
轉移時註意邊界
時間復雜度:\(O(n\ log\ n)\)
代碼
#include <bits/stdc++.h> #define LD long double #define N 100010 using namespace std; struct Node { int p, l, r; } q[N]; int n, p, L, s[N], g[N]; LD f[N]; string st[N]; LD Pow(LD x, int y) { LD ret = 1; while (y) { if (y & 1) ret *= x; y >>= 1, x *= x; } return ret; } LD calc(int x, int y) { return f[y] + Pow(abs(s[x] - s[y] - 1 - L), p); } int solve(int p, int l, int r, int i) { int ans = -1; while (l <= r) { int mid = (l + r) >> 1; if (calc(mid, p) < calc(mid, i)) l = mid + 1; else ans = mid, r = mid - 1; } return ans; } int main() { ios::sync_with_stdio(false); int T; cin >> T; while (T--) { cin >> n >> L >> p; for (int i = 1; i <= n; i++) cin >> st[i], s[i] = s[i - 1] + st[i].size() + 1; int h = 1, t = 1; q[t] = (Node) {0, 1, n}; for (int i = 1; i <= n; i++) { while (h <= t && q[h].r < i) h++; f[i] = calc(i, q[h].p), g[i] = q[h].p; if (h > t || calc(n, q[t].p) > calc(n, i)) { while (h <= t && calc(q[t].l, q[t].p) > calc(q[t].l, i)) t--; if (h <= t) { int x = solve(q[t].p, q[t].l, n, i); q[t].r = x - 1, q[++t] = (Node) {i, x, n}; } else q[++t] = (Node) {i, i, n}; } } if (f[n] <= 1e18) cout << (long long)(f[n] + 0.5) << "\n"; else cout << "Too hard to arrange\n"; cout << "--------------------\n"; } return 0; }
bzoj 1563 [NOI2009]詩人小G 決策單調性+dp