# BZOJ 1564: [NOI2009]二叉查找树( dp )

-------------------------------------------------------------------------------

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>

using namespace std;

typedef long long ll;

const int maxn = 79;
const ll inf = 1LL << 60;

int N, C, H[maxn];
ll dp[maxn][maxn][maxn];

template<class T>
inline void Min(T &x, T t) {
if(t < x) x = t;
}

struct Node {
int d, v, p;
bool operator < (const Node &o) const {
return d < o.d;
}
} o[maxn];

ll Dp(int l, int r, int v) {
if(l > r) return 0;
ll &t = dp[l][r][v];
if(~t) return t;
int d = o[r].p - o[l - 1].p;
if(l == r)
return t = d + (o[l].v >= v ? 0 : C);
t = inf;
for(int i = l; i <= r; i++) {
Min(t, Dp(l, i - 1, v) + Dp(i + 1, r, v) + C + d);
if(o[i].v >= v)
Min(t, Dp(l, i - 1, o[i].v) + Dp(i + 1, r, o[i].v) + d);
}
return t;
}

int main() {
scanf("%d%d", &N, &C);
for(int i = 1; i <= N; i++) scanf("%d", &o[i].d);
for(int i = 1; i <= N; i++) scanf("%d", &o[i].v);
for(int i = 1; i <= N; i++) scanf("%d", &o[i].p);
sort(o + 1, o + N + 1);
o[0].p = 0;
for(int i = 1; i <= N; i++) {
o[i].p += o[i - 1].p;
H[i - 1] = o[i].v;
}
sort(H, H + N);
int hn = unique(H, H + N) - H;
for(int i = 1; i <= N; i++)
o[i].v = lower_bound(H, H + hn, o[i].v) - H;
memset(dp, -1, sizeof dp);
ll ans = inf;
for(int i = 0; i < hn; i++)
Min(ans, Dp(1, N, i));
cout << ans << "\n";
return 0;
}

-------------------------------------------------------------------------------

## 1564: [NOI2009]二叉查找树

Time Limit: 10 Sec  Memory Limit: 64 MB
Submit: 625  Solved: 453
[Submit][Status][Discuss]

4 10
1 2 3 4
1 2 3 4
1 2 3 4

29

## Source

posted @ 2016-02-13 21:54  JSZX11556  阅读(586)  评论(0编辑  收藏  举报