您的位置:首页 > 其它

【BZOJ1563】【NOI2009】诗人小G

2018-03-29 13:42 295 查看
【题目链接】
点击打开链接

【思路要点】
该DP具有决策单调性,以此优化DP即可。
时间复杂度\(O(NLogNLogP)\)。
【代码】
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 100005;
template <typename T> void chkmax(T &x, T y) {x = max(x, y); }
template <typename T> void chkmin(T &x, T y) {x = min(x, y); }
template <typename T> void read(T &x) {
x = 0; int f = 1;
char c = getchar();
for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';
x *= f;
}
template <typename T> void write(T x) {
if (x < 0) x = -x, putchar('-');
if (x > 9) write(x / 10);
putchar(x % 10 + '0');
}
template <typename T> void writeln(T x) {
write(x);
puts("");
}
char st[MAXN];
int n, l, p, k[MAXN];
int a[MAXN], s[MAXN];
long double f[MAXN];
long double power(long double x, int p) {
if (p == 0) return 1;
long double tmp = power(x, p / 2);
if (p % 2 == 0) return tmp * tmp;
else return tmp * tmp * x;
}
long double calc(int k, int x) {
return f[k] + power(abs(s[x] - s[k] + x - k - 1 - l), p);
}
int main() {
int T; read(T);
while (T--) {
read(n), read(l), read(p);
for (int i = 1; i <= n; i++) {
scanf("\n%s", st);
a[i] = strlen(st);
s[i] = s[i - 1] + a[i];
}
int l = 0, r = 0;
static int q[MAXN], ql[MAXN], qr[MAXN];
q[0] = 0, ql[0] = 1, qr[0] = n;
for (int i = 1; i <= n; i++) {
while (l < r && i > qr[l]) l++;
f[i] = calc(q[l], i);
if (calc(i, n) < calc(q[r], n)) {
while (l <= r && calc(q[r], ql[r]) >= calc(i, ql[r])) r--;
if (l > r) {
r++;
q[r] = i;
ql[r] = i + 1;
qr[r] = n;
} else {
int pl = ql[r], pr = qr[r] + 1;
while (pl < pr) {
int mid = (pl + pr) / 2;
if (calc(q[r], mid) < calc(i, mid)) pl = mid + 1;
else pr = mid;
}
qr[r] = pl - 1;
r++;
q[r] = i;
ql[r] = pl;
qr[r] = n;
}
}
}
if (f
> 1e18) printf("Too hard to arrange\n");
else printf("%.0Lf\n", f
);
printf("--------------------\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: