NOI 2009 诗人小G

推荐阅读

这道题调的我天昏地暗

dp就是太难调

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
const int N = 100005;

long double Pow(long double a, int b) {
	long double res = 1, base = a;
	while (b) {
		if (b & 1) res = res * base;
		base = base * base;
		b >>= 1;
	}
	return res;
}

class Solution {
	int n, l, p;
	int w[N], q[N], c[N];
	long double f[N];
	long double Calc(int j, int i) {
		return f[j] + Pow(abs(w[i] - w[j] - l), p);
	}
	int TwoDivide(int c1, int c2) {
		int l = c1, r = n + 1, mid;
		while (l <= r) {
			mid = l + r >> 1;
			if (Calc(c1, mid) >= Calc(c2, mid)) r = mid - 1;
			else l = mid + 1;
		}
		return l;
	}
public:
	Solution() { }
	void Solve(int _, int __, int ___) {
		n = _, l = __ + 1, p = ___;
		std:: string str; 
		for (int i = 1; i <= n; i += 1)
			std:: cin >> str, w[i] = w[i - 1] + str.size() + 1;
		int h = 1, t = 1;
		for (int i = 1; i <= n; i += 1) {
			while (h < t and c[h] <= i) h += 1;
			f[i] = Calc(q[h], i);
			while (h < t and c[t - 1] >= TwoDivide(q[t], i)) t -= 1;
			c[t] = TwoDivide(q[t], i), q[++t] = i;
		}
		if (f[n] > 1e18) printf("Too hard to arrange\n");
		else printf("%.0Lf\n", f[n]);
		puts("--------------------");
	}
};

int main () {
	int T;
	scanf("%d", &T);
	for (int i = 0; i < T; i += 1) {
		int n, l, p;
		scanf("%d%d%d", &n, &l, &p);
		Solution* Sol = new Solution();
		Sol->Solve(n, l, p);
		delete Sol;
	}
	return 0;
}
posted @ 2018-10-11 18:00  Grary  阅读(144)  评论(0)    收藏  举报
博客园 首页 私信博主 编辑 关注 管理 新世界