zoukankan      html  css  js  c++  java
  • bzoj 1564 [NOI2009]二叉查找树(树形DP)

    【题目链接】

        http://www.lydsy.com/JudgeOnline/problem.php?id=1564

    【题意】

        给定一个Treap,总代价为深度*距离之和。可以每次以K的代价修改权值,问最小代价。

    【思路】

        数据值是不变的,因此Treap的中序遍历是唯一的。先将数据按照数据值排序,得到其中序遍历。

      然后将权值离散化到[1,n]区间内。

        设f[l][r][w]为区间[l,r]内的权值都比w大时的最小代价,则有转移式:

            f[l][r][w]=min { f[l][k-1][w]+f[k+1][r][w]+K+c(l,r) }

           f[l][r][w]=min { f[l][k-1][a[k].w]+f[k+1][r][a[k].w]+c(l,r) },a[k].w>=w

        记忆化搜索比较好写lalala

    【代码】

     1 #include<set>
     2 #include<cmath>
     3 #include<queue>
     4 #include<vector>
     5 #include<cstdio>
     6 #include<cstring>
     7 #include<iostream>
     8 #include<algorithm>
     9 #define trav(u,i) for(int i=front[u];i;i=e[i].nxt)
    10 #define FOR(a,b,c) for(int a=(b);a<=(c);a++)
    11 using namespace std;
    12 
    13 typedef long long ll;
    14 const int N = 105;
    15 const int inf = 1e9;
    16 
    17 struct Node 
    18 {
    19     int dat,w,c;
    20     bool operator < (const Node& rhs) const 
    21     {
    22         return dat<rhs.dat;
    23     }
    24 } a[N];
    25 
    26 int n,K,sumc[N],f[N][N][N];
    27 pair<int,int> b[N];
    28 
    29 int dp(int l,int r,int w)
    30 {
    31     int& ans=f[l][r][w];
    32     if(l>r) return ans=0;
    33     if(ans!=-1) return ans;
    34     ans=inf;
    35     FOR(k,l,r) {
    36         if(a[k].w>=w)
    37             ans=min(ans,dp(l,k-1,a[k].w)+dp(k+1,r,a[k].w)+sumc[r]-sumc[l-1]);
    38         ans=min(ans,dp(l,k-1,w)+dp(k+1,r,w)+sumc[r]-sumc[l-1]+K);
    39     }
    40     return ans;
    41 }
    42 
    43 int main()
    44 {
    45 //    freopen("in.in","r",stdin);
    46 //    freopen("out.out","w",stdout);
    47     memset(f,-1,sizeof(f));
    48     scanf("%d%d",&n,&K);
    49     FOR(i,1,n) scanf("%d",&a[i].dat);
    50     FOR(i,1,n) scanf("%d",&a[i].w);
    51     FOR(i,1,n) scanf("%d",&a[i].c);
    52     sort(a+1,a+n+1);
    53     FOR(i,1,n)
    54         b[i]=make_pair(a[i].w,i);
    55     sort(b+1,b+n+1);
    56     FOR(i,1,n)
    57         a[b[i].second].w=i,
    58         sumc[i]=sumc[i-1]+a[i].c;
    59     
    60     int ans=inf;
    61     FOR(i,1,n)
    62         ans=min(ans,dp(1,n,i));
    63     printf("%d",ans);
    64     return 0;
    65 }
  • 相关阅读:
    EM
    te2
    te
    XLnet
    GPT
    40.Properties
    38.特殊操作流
    37.I/O流
    35.File
    day68日考
  • 原文地址:https://www.cnblogs.com/lidaxin/p/5348089.html
Copyright © 2011-2022 走看看