【BZOJ1564】[NOI2009]二叉查找树【区间DP】

【题目链接】

这是一棵Treap,而且我们知道BST的中序遍历的数据值是递增的,那么我们按照数据值排个序,就得到中序遍历了。然后就变成区间DP啦。

设dp[l][r][m]表示,区间[l, r]的节点组成的树中的,根节点的权值≥m的最小代价。

然后枚举根节点转移。

(1)将根节点i的权值修改为m,有dp[l][r][m] = dp[l][i – 1][m] + dp[i + 1][r][m] + K

(2)根节点i的权值≥m时,dp[l][r][m] = dp[l][i – 1][i的权值 + 1] + dp[i + 1][r][i的权值 + 1]

求得dp[l][r][m]最小值后,再给dp[l][r][m]加上[l, r]每个节点的访问频度

/* Pigonometry */
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

typedef long long LL;

const int maxn = 75;
const LL inf = 0x3f3f3f3f3f3f3f3f;

int n, K, tot, disc[maxn];
LL dp[maxn][maxn][maxn];

struct _data {
	int val, w, fre;

	bool operator < (const _data &x) const {
		return val < x.val;	
	}
} A[maxn];

inline int iread() {
	int f = 1, x = 0; char ch = getchar();
	for(; ch < '0' || ch > '9'; ch = getchar()) f = ch == '-' ? -1 : 1;
	for(; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';
	return f * x;
}

inline int find(int x) {
	int l = 1, r = tot;
	while(l <= r) {
		int mid = l + r >> 1;
		if(disc[mid] < x) l = mid + 1;
		else if(disc[mid] == x) return mid;
		else r = mid - 1;
	}
}

inline LL dfs(int l, int r, int lb) {
	if(l > r) return 0;
	if(~dp[l][r][lb]) return dp[l][r][lb];

	LL res = inf;
	for(int i = l; i <= r; i++) {
		res = min(res, dfs(l, i - 1, lb) + dfs(i + 1, r, lb) + K);
		if(A[i].w >= lb) res = min(res, dfs(l, i - 1, A[i].w + 1) + dfs(i + 1, r, A[i].w + 1));
	}
	res += A[r].fre - A[l - 1].fre;
	return dp[l][r][lb] = res;
}

int main() {
	n = iread(); K = iread();
	for(int i = 1; i <= n; i++) A[i].val = iread();
	for(int i = 1; i <= n; i++) disc[i] = A[i].w = iread();
	for(int i = 1; i <= n; i++) A[i].fre = iread();

	sort(A + 1, A + 1 + n);
	sort(disc + 1, disc + 1 + n);
	tot = unique(disc + 1, disc + 1 + n) - (disc + 1);
	for(int i = 1; i <= n; i++) A[i].w = find(A[i].w), A[i].fre += A[i - 1].fre;

	memset(dp, -1, sizeof(dp));
	printf("%lld\n", dfs(1, n, 1));
	return 0;
}
    原文作者:二叉查找树
    原文地址: https://blog.csdn.net/BraketBN/article/details/51250643
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞