cf 987C

n個位置,每個位置有兩個屬性s,c,要求選擇3個位置i,j,k,使得si<sj<sk,並使得ci+cj+ck 最小
輸入格式:
一行一個整數,n,3<=n<=3000
一行n個整數,即s
再一行n個整數,即c
動態規劃 + 權值線段樹優化。時間複雜度 O(nlog(n))

#include <bits/stdc++.h>
using namespace std;
const int inf = 1e9;
const int maxn = 1e6 + 5;
struct Tree {
	int l, r, mm;
}tree[maxn];
int L[maxn], R[maxn], s[maxn], c[maxn];
int Hash[maxn], len;
void pushup(int i) {
	tree[i].mm = min(tree[i * 2].mm, tree[i * 2 + 1].mm);
}

void build(int i, int l, int r) {
	tree[i].l = l;
	tree[i].r = r;
	tree[i].mm = inf;
	if (l >= r) return ;
	int mid = (l + r) / 2;
	build(i * 2, l, mid);
	build(i * 2 + 1, mid + 1, r);
	pushup(i);
}

void updata(int i, int p, int v) {
	if (tree[i].l == tree[i].r) {
		tree[i].mm = min(tree[i].mm, v);
		return ;
	}
	int mid = (tree[i].l + tree[i].r) / 2;
	if (mid >= p) {
		updata(i * 2, p, v);
	} else {
		updata(i * 2 + 1, p, v);
	}
	pushup(i);
}

int query(int i, int l, int r) {
	if (l > r) return inf;
	if (tree[i].l == l && tree[i].r == r) {
		return tree[i].mm;
	}
	int mid = (tree[i].l + tree[i].r) / 2;
	if (mid >= r) {
		return query(i * 2, l, r);
	} else if (l > mid) {
		return query(i * 2 + 1, l, r);
	} else {
		return min(query(i * 2, l, mid), query(i * 2 + 1, mid + 1, r));
	}
}

int main() {
	int n;
	cin >> n;
	for (int i = 1; i <= n; i++) {
		cin >> s[i];
		Hash[++len] = s[i];
	}
	for (int i = 1; i <= n; i++) {
		cin >> c[i];
	}
	sort (Hash + 1, Hash + len + 1);
	len = unique(Hash + 1, Hash + len + 1) - Hash - 1;
	for (int i = 1; i <= n; i++) {
		s[i] = lower_bound(Hash + 1, Hash + len + 1, s[i]) - Hash;
	}
	build(1, 1, len);
	for (int i = 1; i <= n; i++) {
		L[i] = query(1, 1, s[i] - 1);
		updata(1, s[i], c[i]);
	}
	build(1, 1, len);
	for (int i = n; i >= 1; i--) {
		R[i] = query(1, s[i] + 1, len);
		updata(1, s[i], c[i]);
	}
	int ans = inf;
	for (int i = 1; i <= n; i++) {
		ans = min(ans, L[i] + R[i] + c[i]);
	}
	if (ans != inf) {
		cout << ans << endl;
	} else {
		cout << "-1" << endl;
	}
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章