记录编号 412694 评测结果 AAAAAAAAAA
题目名称 [NOI 2009]二叉查找树 最终得分 100
用户昵称 GravatarImone NOI2018Au 是否通过 通过
代码语言 C++ 运行时间 0.172 s
提交时间 2017-06-09 20:25:04 内存使用 3.51 MiB
显示代码纯文本
  1. #include <cstring>
  2. #include <cstdio>
  3. #include <algorithm>
  4. #define ll long long
  5. #define MAXN 75
  6. using namespace std;
  7.  
  8. ll dp[MAXN][MAXN][MAXN], K; //[i, j, p] pi >= p
  9. ll sum[MAXN];
  10.  
  11. struct item {
  12. int v, f, p;
  13. } A[MAXN];
  14.  
  15. inline bool cmpv(item a, item b) {
  16. return a.v < b.v;
  17. }
  18. inline bool cmpp(item a, item b) {
  19. return a.p < b.p;
  20. }
  21.  
  22. int N;
  23.  
  24. int main() {
  25. freopen("treapmod.in", "rt", stdin);
  26. freopen("treapmod.out", "wt", stdout);
  27. int i, t;
  28. scanf("%d%lld", &N, &K);
  29. for(i=1;i<=N;i++) scanf("%d", &A[i].v);
  30. for(i=1;i<=N;i++) scanf("%d", &A[i].p);
  31. for(i=1;i<=N;i++) scanf("%d", &A[i].f);
  32.  
  33. sort(A+1, A+N+1, cmpp);
  34. for(i=1;i<=N;i++) A[i].p = i;
  35.  
  36. sort(A+1, A+N+1, cmpv);
  37. for(i=1;i<=N;i++) sum[i] = sum[i-1] + A[i].f;
  38.  
  39. int len, j, k, root;
  40. memset(dp, 0x3f, sizeof(dp));
  41.  
  42. for(k=1;k<=N;k++) for(i=0;i<=N;i++) dp[i+1][i][k] = 0;
  43. for(len=1;len<=N;len++) for(i=1;(j=(i+len-1))<=N;i++) for(k=1;k<=N;k++) {
  44. for(root=i;root<=j;root++) {
  45. if(A[root].p >= k) dp[i][j][k] = min(dp[i][j][k], dp[i][root-1][A[root].p] + dp[root+1][j][A[root].p] + sum[j] - sum[i-1]);
  46. dp[i][j][k] = min(dp[i][j][k], dp[i][root-1][k] + dp[root+1][j][k] + sum[j] - sum[i-1] + K);
  47. }
  48. }
  49. printf("%lld", dp[1][N][1]);
  50. }