• 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 }
  • 相关阅读:
    UIScrollView的滚屏
    ASIHTTPRequest 详解, 够详细
    Libxml2中使用xpath解析xml问题
    new Random()结果相同问题
    UINavigationController使用的一些技巧
    Objectivec 模拟http请求
    开发视频网站,asp.net视频文件转换.flv格式(转)
    jqueryjCarousel 配置选项
    NSDate和NSString之间的转换,(可以转时区的哈)
    NSLog的格式
  • 原文地址:https://www.cnblogs.com/lidaxin/p/5348089.html
Copyright © 2020-2023  润新知