题意:给你一颗完全二叉树,每条边有一个值,可以对这个值进行加操作,让你满足根节点到所有叶子节点路径值相同 ,问你最少要加多少值。
解题思路:从上往下树形DP,位运算会比较方便。
解题代码:

1 // File Name: b.cpp
2 // Author: darkdream
3 // Created Time: 2015年04月05日 星期日 00时47分32秒
4
5 #include<vector>
6 #include<list>
7 #include<map>
8 #include<set>
9 #include<deque>
10 #include<stack>
11 #include<bitset>
12 #include<algorithm>
13 #include<functional>
14 #include<numeric>
15 #include<utility>
16 #include<sstream>
17 #include<iostream>
18 #include<iomanip>
19 #include<cstdio>
20 #include<cmath>
21 #include<cstdlib>
22 #include<cstring>
23 #include<ctime>
24 #define LL long long
25
26 using namespace std;
27 int num ;
28 void solve(int n)
29 {
30 num = 1;
31 for(int i = 1;i <= n+1;i ++)
32 {
33 num *= 2;
34 }
35 num -- ;
36 }
37 int dp[5000];
38 int a[5000];
39 int ans = 0 ;
40 int Abs(int tt)
41 {
42 if(tt >=0 )
43 return tt;
44 return -tt;
45 }
46 void dfs(int k)
47 {
48 if(k > num)
49 return;
50 dfs(2*k);
51 dfs(2*k+1);
52 dp[k] = max(dp[2*k] + a[2*k-1],dp[2*k+1] + a[2*k]);
53 int ta = dp[2*k] + a[2*k-1];
54 int tb = dp[k*2+1] + a[2*k];
55 ans += Abs(ta-tb);
56 }
57 int main(){
58 int n;
59 scanf("%d",&n);
60 solve(n);
61 for(int i = 1;i< num;i ++)
62 scanf("%d",&a[i]);
63 dfs(1);
64 printf("%d\n",ans);
65 return 0;
66 }
来源:https://www.cnblogs.com/zyue/p/4394772.html
