zoukankan      html  css  js  c++  java
  • BZOJ 1564: [NOI2009]二叉查找树( dp )

    树的中序遍历是唯一的. 按照数据值处理出中序遍历后, dp(l, r, v)表示[l, r]组成的树, 树的所有节点的权值≥v的最小代价(离散化权值).

    枚举m为根(p表示访问频率):

    修改m的权值 : dp(l, r, v) = min( dp(l, m-1, v) + dp(m+1, r, v) + p(l~r) + K )

    不修改(m原先权值≥v) : dp(l, r, v) = min( dp(l, m-1, Value(m)) + dp(m+1, r, Value(m)) + p(l~r) )

    时间复杂度O( N log N + N^4 ) 

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

    #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 << " ";
    return 0;
    }

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

    1564: [NOI2009]二叉查找树

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

    Description

    Input

    Output

    只有一个数字,即你所能得到的整棵树的访问代价与额外修改代价之和的最小值。

    Sample Input

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

    Sample Output

    29

    HINT

    输入的原图是左图,它的访问代价是1×1+2×2+3×3+4×4=30。最佳的修改方案是把输入中的第3个结点的权值改成0,得到右图,访问代价是1×2+2×3+3×1+4×2=19,加上额外修改代价10,一共是29。

    Source

  • 相关阅读:
    <<SQL Server 2005 高级程序设计>> 学习笔记(4)
    ASP.NET发布网站的二个小问题总结
    Android AlertDialog 实例
    SQL2005 导入其它服务器数据
    Android sysout.exit(0) 和finish()区别
    <<SQL Server 2005 高级程序设计>> 学习笔记(3)
    ASP.NET上传多个文件
    <<SQL Server 2005 高级程序设计>> 学习笔记(1)
    SurfaceView 间取得焦点
    图像处理类
  • 原文地址:https://www.cnblogs.com/JSZX11556/p/5188328.html
Copyright © 2011-2022 走看看