codeforces 633F The Chocolate Spree (树形dp)"/>
codeforces 633F The Chocolate Spree (树形dp)
题目链接:
题解:看起来很像是树形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\n" , dp[1][2]);return 0; }
转载于:.html
更多推荐
codeforces 633F The Chocolate Spree (树形dp)
发布评论