zoukankan      html  css  js  c++  java
  • codeforces 633F The Chocolate Spree (树形dp)

    题目链接:http://codeforces.com/problemset/problem/633/F

    题解:看起来很像是树形dp其实就是单纯的树上递归,就是挺难想到的。

    显然要求最优解肯定是取最大的两条链不妨设dp[i][3],dp[i][1]表示以i为根节点的子树val最大的子链,dp[i][2]表示以i为根节点的子树val最大的两条子链。

    显然dp[i][2]=max(dp[i][2],dp[i][1]+dp[v][1]) (v  表示i的子节点)

    dp[i][2]=max(dp[i][2],down[i]+mmp[v]) (down[i]表示的是以i为根节点到子叶val最大的,mmp[v]表示以v为根节点的到子也最大值再加上一条最大的链的值)

    dp[i][2]=max(dp[i][2],down[v]+mmp[i])

    其实这些都是挺形象的几种可能性画一下图就知道了。

    剩下的down的转移和mmp的转移具体看一下代码。这里还会涉及到一个bs[i]表示以dp[v][1]的最大值。

    然后这些东西都通过递归dfs就行了。dfs是个神奇的东西

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <vector>
    using namespace std;
    typedef long long ll;
    const int M = 1e5 + 10;
    int a[M];
    vector<int> vc[M];
    ll dp[M][3] , down[M] , mmp[M] , bs[M];
    void dfs(int u , int pre) {
        int len = vc[u].size();
        dp[u][1] = a[u];
        dp[u][2] = a[u];
        down[u] = a[u];
        bs[u] = 0;
        mmp[u] = a[u];
        for(int i = 0 ; i < len ; i++) {
            int v = vc[u][i];
            if(v == pre) continue;
            dfs(v , u);
            /////
            dp[u][2] = max(dp[u][2] , dp[v][2]);
            dp[u][2] = max(dp[u][2] , dp[u][1] + dp[v][1]);
            dp[u][2] = max(dp[u][2] , down[u] + mmp[v]);
            dp[u][2] = max(dp[u][2] , down[v] + mmp[u]);
            /////
            dp[u][1] = max(dp[u][1] , dp[v][1]);
            dp[u][1] = max(dp[u][1] , down[v] + down[u]);
            /////
            mmp[u] = max(mmp[u] , mmp[v] + a[u]);
            mmp[u] = max(mmp[u] , dp[v][1] + down[u]);
            mmp[u] = max(mmp[u] , down[v] + bs[u] + a[u]);
            /////
            bs[u] = max(bs[u] , dp[v][1]);
            /////
            down[u] = max(down[u] , down[v] + a[u]);
        }
    }
    int main() {
        int n;
        scanf("%d" , &n);
        for(int i = 1 ; i <= n ; i++) {
            scanf("%d" , &a[i]);
        }
        for(int i = 1 ; i < n ; i++) {
            int u , v;
            scanf("%d%d" , &u , &v);
            vc[u].push_back(v);
            vc[v].push_back(u);
        }
        dfs(1 , 0);
        printf("%lld
    " , dp[1][2]);
        return 0;
    }
  • 相关阅读:
    css 父层 透明 子层不透明Alpha
    ecshop循环foreach,iteration,key,index
    ecshop变量介绍
    ecshop 获取某个商品的 所有订单信息 或者销量
    echosp 销量排行 新增实际价格
    ecshop后台模板设置中将非可编辑区改为可编辑区
    ecshop 影响全局的标量lib_main.php
    个人js
    fixed的left:50%,漂浮
    js返回顶部
  • 原文地址:https://www.cnblogs.com/TnT2333333/p/7754108.html
Copyright © 2011-2022 走看看