题意:给你一颗完全二叉树,每条边有一个值,可以对这个值进行加操作,让你满足根节点到所有叶子节点路径值相同 ,问你最少要加多少值。
解题思路:从上往下树形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 }
没有梦想,何谈远方