题意:给你一颗完全二叉树,每条边有一个值,可以对这个值进行加操作,让你满足根节点到所有叶子节点路径值相同  ,问你最少要加多少值。

解题思路:从上往下树形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 }
View Code

 

posted on 2015-04-05 21:07  dark_dream  阅读(276)  评论(0编辑  收藏  举报