记录编号 578190 评测结果 AAAAAAAAAA
题目名称 [NOI 2009]二叉查找树 最终得分 100
用户昵称 Gravatarzxhhh 是否通过 通过
代码语言 C++ 运行时间 0.355 s
提交时间 2023-02-15 18:30:00 内存使用 5.41 MiB
显示代码纯文本
#include <bits/stdc++.h>

using namespace std;

const int N = 75;
typedef long long ll;

int n, ord[N], t[N], cnt[N][N];
ll dp[N][N][N], k, m[N][N], s[N];

struct node {
	ll a, v, s;
}nodes[N];

bool cmp (node x, node y) { 
	return x.a < y.a;
} 

int main () {
	freopen("treapmod.in", "r", stdin);
	freopen("treapmod.out", "w", stdout);
	memset(m, 0x3f, sizeof(m)); memset(dp, 0x3f, sizeof(dp));
	scanf("%d%lld", &n, &k);
	for (int i = 1;i <= n;i++) scanf("%lld", &nodes[i].a);
	for (int i = 1;i <= n;i++) scanf("%lld", &nodes[i].v);
	for (int i = 1;i <= n;i++) scanf("%lld", &nodes[i].s);
	sort(nodes + 1, nodes + 1 + n, cmp);
	for (int i = 1;i <= n;i++) t[i] = nodes[i].v;
	sort(t + 1, t + 1 + n);
	for (int i = 1;i <= n;i++) ord[i] = lower_bound (t + 1, t + 1 + n, nodes[i].v) - t;
//	for (int i = 1;i <= n;i++) cout << nodes[i].v << " " << ord[i] << endl;
	for (int i = 1;i <= n;i++) {
		s[i] = s[i - 1] + nodes[i].s;
		for (int j = 1;j <= n;j++) {
			cnt[i][j] = cnt[i - 1][j];
			if (ord[i] < j) cnt[i][j]++;
		}
	}
	for (int i = 1;i <= n;i++) {
		for (int j = 0;j <= ord[i] - 1;j++) dp[i][i][j] = nodes[i].s;
		for (int j = ord[i];j <= n;j++) dp[i][i][j] = nodes[i].s;
	}
	for (int l = 2;l <= n;l++) {
		for (int i = 1;i + l - 1 <= n;i++) {
			int j = i + l - 1;
			for (int g = 0;g <= n;g++) {
				for (int z = i;z <= j;z++) {
					ll ls = 0, rs = 0;
					if (ord[z] <= g) {
						if (z > i) ls = dp[i][z - 1][g];
						if (z < j) rs = dp[z + 1][j][g];
						dp[i][j][g] = min(dp[i][j][g], ls + rs + s[j] - s[i - 1]);
					}
					else {
						int x = cnt[j][ord[z]] - cnt[i - 1][ord[z]] - (cnt[j][g + 1] - cnt[i - 1][g + 1]);
						if (z > i) ls = dp[i][z - 1][ord[z]];
						if (z < j) rs = dp[z + 1][j][ord[z]];
						dp[i][j][g] = min(dp[i][j][g], ls + rs + s[j] - s[i - 1] + x * k);
						if (z > i) ls = dp[i][z - 1][g];
						if (z < j) rs = dp[z + 1][j][g];
						dp[i][j][g] = min(dp[i][j][g], ls + rs + s[j] - s[i - 1] + k);
					}
//					if (z > i) ls = dp[i][z - 1];
//					if (z < j) rs = dp[z + 1][j];
//					dp[i][j][g] = min(dp[i][j][g], ls + rs + ad + s[j] - s[i - 1]);
				}
//				cout << i << " " << j << " " << g << " " << dp[i][j][g] << endl; 
			}
				
		}
	}
//	for (int i = 0;i <= n;i++) printf("%lld ", dp[1][n][i]);
	printf("%lld\n", dp[1][n][0]);
	return 0;
}