这玩意儿就是一个Treap对吧
因为key值可以选择任意实数,所以修改之后的key值
F[l][r][w]
表示构建l到r的Treap并且根节点的key值为w所需要的最小代价
O(n3)
状态,
O(n)
转移,总时间
O(n4)
/**************************************************************
Problem: 1564
User: di4CoveRy
Language: C++
Result: Accepted
Time:472 ms
Memory:5816 kb
****************************************************************/
#include <iostream>
#include <cstdio>
#include <algorithm>
#define N 105
#define INF (1<<29)
using namespace std;
struct Monster{ int tr,key,v; }Q[N];
int e[N],sum[N],vis[N][N][N];
int n,k;
inline void ut(int &x,int y) { x = min(x,y); }
bool cmpe(int p1,int p2) { return Q[p1].key < Q[p2].key; }
bool cmpq(Monster p1,Monster p2) { return p1.tr < p2.tr; }
int F(int l,int r,int w) {
if (l > r) return 0;
if (vis[l][r][w]) return vis[l][r][w];
int ret = INF;
if (l == r) return Q[l].key >= w ? Q[l].v : Q[l].v + k;
for (int _=l;_<=r;_++) {
ut(ret , F(l,_-1,w) + F(_+1,r,w) + (sum[r]-sum[l-1]) + k);
if (w <= Q[_].key)
ut(ret , F(l,_-1,Q[_].key) + F(_+1,r,Q[_].key) + (sum[r]-sum[l-1]) );
}
return vis[l][r][w] = ret;
}
int main() {
scanf("%d%d",&n,&k);
for (int _=1;_<=n;_++) scanf("%d",&Q[_].tr);
for (int _=1;_<=n;_++) scanf("%d",&Q[_].key);
for (int _=1;_<=n;_++) scanf("%d",&Q[_].v);
for (int _=1;_<=n;_++) e[_] = _;
sort(e+1,e+n+1,cmpe);
for (int _=1;_<=n;_++) Q[ e[_] ].key = _;
sort(Q+1,Q+n+1,cmpq);
for (int _=1;_<=n;_++) sum[_] = sum[_-1] + Q[_].v;
int ans = INF;
for (int _=1;_<=n;_++) ut(ans,F(1,n,_));
printf("%d\n",ans);
return 0;
}