Codeforces 526B Om Nom and Dark Park 树形dp

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

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

时间: 2024-08-09 14:35:49

Codeforces 526B Om Nom and Dark Park 树形dp的相关文章

ZeptoLab Code Rush 2015 B. Om Nom and Dark Park DFS

B. Om Nom and Dark Park Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/526/problem/B Description Om Nom is the main character of a game "Cut the Rope". He is a bright little monster who likes visiting friends living a

B. Om Nom and Dark Park

B. Om Nom and Dark Park 在满二叉树上的某些边上添加一些值.使得根节点到叶子节点的路径上的权值和都相等.求最少需要添加多少. 我们利用性质解题.   考察兄弟节点.由于他们从跟节点到父节点这路径是相同的,所以需要添加的值为  2*max(lch,rch)-lch-rch;  同时将max(lch,rch)累加到父节点. 思路是最重要的.有时候不是聪不聪明的问题,而是会不会思考的问题. 1 #include <iostream> 2 #include <cstdio&

ZeptoLab Code Rush 2015 B. Om Nom and Dark Park

1.题目描述:点击打开链接 2.解题思路:比赛时候这道题没有做出来,第二天早晨补题时才发现就是简单的DFS应用.题目要求出最少需要增加几盏路灯.假设我们已经知道了root的左子结点一共有suml盏路灯,右子结点一共有sumr盏路灯,那么比较一下d[lson(root)]+suml和d[rson(root)]+sumr的大小即可.此时需要增加的路灯数量就是两者差的绝对值.同时返回较大的数即得到root的总路灯数量. 3.代码: #define _CRT_SECURE_NO_WARNINGS #in

Codeforces C - Om Nom and Candies

C - Om Nom and Candies 思路:贪心+思维(或者叫数学).假设最大值max(wr,wb)为wr,当c/wr小于√c时,可以枚举r糖的数量(从0到c/wr),更新答案,复杂度√c:否则,假设hr/wr<hb/wr,得到hr*wb<hb*wr,由这个等式可知,在有wb*wr重量限制的情况下,买wb个r糖没有买wr个b糖划算,当需要买超过wb个r糖时,不如去买b糖,可以枚举r糖的数量(从0到wb-1),更新答案,复杂度√c. 代码: #include<bits/stdc++

Codeforces 526D - Om Nom and Necklace 【KMP】

ZeptoLab Code Rush 2015 D. Om Nom and Necklace [题意] 给出一个字符串s,判断其各个前缀是否是 ABABA…ABA的形式(A和B都可以为空,且A有Q+1个,B有Q个,Q给定). [官方题解] 对于前缀P,我们可以把它拆成P=SSSS…SSSST,其中T是S的前缀.显然可以用KMP算法,时间复杂度是O(n). 当T=S:P=SSS…S.假设S出现了R次.如果转换为ABABAB…ABABA的形式,A和B是由几个S组成,而且最后的A一定是P的一个后缀.由

Codeforces 526C - Om Nom and Candies

A sweet little monster Om Nom loves candies very much. One day he found himself in a rather tricky situation that required him to think a bit in order to enjoy candies the most. Would you succeed with the same task if you were on his place? One day,

codeforces 161 D. Distance in Tree(树形dp)

题目链接:http://codeforces.com/problemset/problem/161/D 题意:给出一个树,问树上点到点的距离为k的一共有几个. 一道简单的树形dp,算是一个基础题. 设dp[i][len]表示i为根距离为len的一共有几个点. 一般的树形dp都是先dfs然后再更新dp的值,注意按这样写就行了.而且一般的树形dp都是设dp[i][k]i为根,k为条件. void dfs(int u , int pre) { int len = vc[u].size(); dp[u]

codeforces 500D - New Year Santa Network (树形DP+组合数学)

题目地址:http://codeforces.com/contest/500/problem/D 这题是要先求出每条边出现的次数,然后除以总次数,这样期望就求出来了.先用树形DP求出每个边左右两端总共有多少个点,然后用组合数学公式就可以推出来了. 代码如下: #include <iostream> #include <string.h> #include <math.h> #include <queue> #include <algorithm>

Codeforces 219D Choosing Capital for Treeland(树形DP)

题目是给一张边有向的树形图.要选出首都的点,首都要都能走到其他点,因此要反转一些边的方向.问可以选哪几个点作为首都,使它们所需反转边的数量最少. 这题挺好想的,因为做过HDU2196. 首先就不妨设正向边权值为0,反向边权值为1,那样就是各个点出发到其他点经过边所需的最少权值和. 然后对于每个点,分两个部分考虑:以这个点为根的子树.这个点往上走的部分: dp[0][u]表示以u点作为首都且以u点为根的子树部分所需反转边的数量,容易知道就等于子树内边权和 dp[1][u]表示以u点作为首都且u点向