- 树上的动态规划,即树形DP。做树形DP一般步骤是先将树转换为有根树,然后在树上进行深搜操作,从子节点或子树中返回信息层层往上更新至根节点。
例题1.星象仪
【问题描述】
在寂寞的夜里,星象仪是非常浪漫的东西。但是,你作为一个精神稍微有点不太正常的Geek,把原本正常的星象仪改造得像电报发送器一样。当然,你这个的构造还要更加奇葩一点。具体来说,你的星象仪是一棵满二叉树,二叉树的节点都是有两个输入端和一个输出端的AND 门或者OR 门。它们输入和输出的信号都是只是0 或者1。它们会接受子节点的输出信号,然后将这两个信号进行AND 运算或者OR 运算作为自己的输出。然后,根节点的输出信号就是整个星象仪的输出信号。叶节点的输入信号是由你来调整的,如果二叉树有K 层,那么你显然有2K 个输入信号可以调整。调整一次当然只能改变一个输入信号。根据你的设定,在一开始所有的输入端的输入信号都是0。现在你希望用星象仪得到一串信号,为此,你需要不停地调整输入。
假定你想要用上图中的星象仪得到输出信号000111,一种可行的方案是0001→0011→1100→1111→1010→0101,但是这样你要调整14 次输入信号。更加方便的方式是0000→0000→0000→0101→0101→0101,这样你总计只需要调整2 次输入信号。由于调整输入信号是一件非常麻烦的事情,现在你希望知道对于一台给定的星象仪,如果想要得到一串给定的信号,至少需要调整多少次输入。
【输入格式】
输入文件包含多组测试数据。第一行有一个整数T,表示测试数据的组数。每组测试数据的第一行是一个正整数N,表示输入信号的数目。保证N 是2 的整数次幂。
第二行含有一个由0 和1 组成的字符串S,表示你想要得到的信号。
第三行包含N – 1 个整数,按照层次遍历顺序给出满二叉树的每个节点。整数只会是0 或者1。0 表示二叉树的这个位置是一个OR 门,1 表示是一个AND 门。
【输出格式】
对于每组测试数据,在单独的一行内输出结果。
【样例】
astrology.in
2
4
010101
0 0 0
4
111111
1 1 1
astrology.out
5
4
- f[i]表示第i输出得到一个1最少需要几次,先对最后的一层进行预处理,即f[ ]都为1,然后对树从下往上进行搜索,如果是AND门,f[i]=f[i*2]+f[i*2+1],如果是OR门,则f[i]=min(f[i*2],f[i*2+1])
- 最后进行判断,具体实现看代码
|
|
2.最大子树和
题目大意:在一个无环无向图中(也可以叫树)删去一些边(及边上带的顶点),使剩下的顶点上的值最大。
树形DP。设f[i]为取i这个顶点的美学最大值。F[i]初始都为map[i],则对于所有与i相连的点f[j],如果f[j]>0就加入到f[i]否则不加。注意f[j]不能再遍历i.最后max(f[i])即为所求。
|
|
3.花花的聚会
4.1 题意描述
花花住在H 国。H 国有n 个城市,其中1 号城市为其首都。城市间有n 1 条单向道
路。从任意一个城市出发,都可以沿着这些单向道路一路走到首都。事实上,从任何一个城市
走到首都的路径是唯一的。
过路并不是免费的。想要通过某一条道路,你必须使用一次过路券。H 国一共有m 种过
路券,每张过路券以三个整数表示:v k w:你可以在城市v 以价格w 买到一张过路券。这
张券可以使用k 次。这意味着,拿着这张券通过了k 条道路之后,这张券就不能再使用了。
请注意你同一时间最多只能拥有最多一张过路券。但你可以随时撕掉手中已有的过路券,
并且在所在的城市再买一张。
花花家在首都。他有q 位朋友,他希望把这些朋友们都邀请到他家做客。所以他想要知道
每位朋友要花多少路费。他的朋友们都很聪明,永远都会选择一条花费最少的方式到达首都。
花花需要准备晚餐去了,所以他没有时间亲自计算出朋友们将要花费的路费。你可以帮帮
他么?
4.2 输入格式
输入的第一行包含两个空格隔开的整数n 和m,表示H 国的城市数量和过路券的种数。
之后的n 1 行各自包含两个数ai 和bi,代表城市ai 到城市bi 间有一条单向道路。
之后的m 行每行包括三个整数vi; ki 和wi,表示一种过路券。
下一行包含一个整数q,表示花花朋友的数量。
之后的q 行各自包含一个整数,表示花花朋友的所在城市。
4.3 输出格式
输出共q 行,每一行代表一位朋友的路费。
4.4 样例输入
7 7
3 1
2 1
7 6
6 3
5 3
4 3
7 2 3
7 1 1
2 3 5
3 6 2
4 2 4
5 3 10
6 1 20
3
5
6
7
4.5 样例输出
10
22
5
4.6 样例解释
对于第一位朋友,他在5 号城市只能购买一种过路券,花费10 元并且可以使用3 次。这
足够他走到首都,因此总花费是10 元。
对于第二位朋友,他在6 号城市只能购买20 元的过路券,并且只能使用一次。之后,他
可以在3 号城市购买2 元,可以使用3 次的过路券走到首都。总花费是22 元。
对于第三位朋友,他在7 号城市可以购买两种过路券。他可以花3 元买一张可以使用2
次的券,然后在3 号城市再买一张2 元,可以使用3 次的券,走到首都。总花费是5 元,而且
其他的购买方式不会比这种更省钱。
4.7 数据规模与约定
• 对于40% 的数据:n; m; q 10;wi 10;
• 另有20% 的数据:n; m; q 500;wi 100;
• 另有20% 的数据:n; m; q 5000;wi 1000;
• 对于100% 的数据:n; m; q 105;wi 10000; 1 vi; ki n。
- 花花2333333想到阿花了,阿花可爱多了不是吗╭(╯^╰)╮。
- 这是一道动态规划,还是一道树形DP,因为题中说明了对于每一个城市只有一条路径到达首都,显而易见就可以建成一个由首都1作为根节点的树。那么记f[u] 为u 跳到根的最少代价。则不难得出转移方程:f[u] = min(f[v]+w[i]),其中v 是u 的祖先,而对于过路券,我们……还是枚举吧,反正可以过[pia]。
代码如下:
|
|