这题和之前那个HDU2616有着奇妙的异曲同工之处。。都是要求某个点能够到达的最大权重的地方。。。

但是,这题加了个限制,要求最多只能够踩到C个陷阱,一单无路可走或者命用光了,就地开始清算总共得分之和。

于是首先考虑,C的大小只有4,那么可以进行非常方便的状态转移,即将之前2616中的各个矩阵都加一维,设定为走到这一步的时候,可以踩得陷阱的个数——如果可以踩得陷阱的个数是0就意味着不能够行走,于是直接规定,所有是0条命的都自动为0。

之后按照上题的方式进行列举,有所不同的是,需要考虑下数组传递参数的方式,我的做法是将临时变量开到全局空间,这样就就可以保证不会爆栈什么的了。

考虑每个点,如果该电有陷阱,那么所有的转移,都必须按是少了一条命的结果,否则就是直接转移,同事我们认为,由于没有点数小于等于0的点,所以,必然可以得出,在同一个点上,当两个人的命数量不相等时,必然会有命多的“最大得分不小于命少的最大得分”。于是只需要普通的更新就是了。

#include<iostream>
#include<vector>
#include<string.h>
#include<stdio.h>
using namespace std; const long long MAXN = ;
vector<int>G[MAXN];
const long long LIMIT = ;
long long child[MAXN][LIMIT];
long long child_left[MAXN][LIMIT];
long long child_right[MAXN][LIMIT];
long long tmp[MAXN][LIMIT];
bool trap[MAXN];
long long arr[MAXN];
long long n, c; long long max(long long a, long long b)
{
return a > b ? a : b;
} void get_child(int now, int last)
{
int len = G[now].size();
for (int i = ; i<LIMIT; ++i)child[now][i] = ;
for (int i = ; i<len; ++i)
{
int tar = G[now][i];
if (tar == last)continue; get_child(tar, now);
if (trap[now])for (int i = ; i<LIMIT; ++i)child[now][i] = max(child[now][i], child[tar][i - ]);
else for (int i = ; i<LIMIT; ++i)child[now][i] = max(child[now][i], child[tar][i]);
}
for (int i = ; i<LIMIT; ++i)child[now][i] += arr[now];
}
void get_left(int now, int last)
{
int len = G[now].size();
if (last == -)
{
memset(child_left[now], , sizeof(child_left));
memset(tmp[now], , sizeof(tmp[now]));
}
else
{
if (trap[now]) for (int i = ; i<LIMIT; ++i) child_left[now][i] = tmp[now][i] = tmp[last][i - ];
else for (int i = ; i<LIMIT; ++i)child_left[now][i] = tmp[now][i] = tmp[last][i]; } for (int i = ; i<LIMIT; ++i)child_left[now][i] += arr[now]; long long ttmp[LIMIT]; memset(ttmp, , sizeof(ttmp));
for (int i = ; i<len; ++i)
{
int tar = G[now][i];
if (tar == last)continue;
for (int j = ; j<LIMIT; ++j)tmp[now][j] = max(tmp[now][j], ttmp[j]);
for (int j = ; j<LIMIT; ++j)tmp[now][j] += arr[now];
get_left(tar, now);
for (int j = ; j<LIMIT; ++j)tmp[now][j] -= arr[now];
if (trap[now]) for (int j = ; j<LIMIT; ++j)ttmp[j] = max(ttmp[j], child[tar][j - ]);
else for (int j = ; j<LIMIT; ++j) ttmp[j] = max(ttmp[j], child[tar][j]);
} }
void get_right(int now, int last)
{
int len = G[now].size(); if (last == -)
{
memset(child_right[now], , sizeof(child_right));
memset(tmp[now], , sizeof(tmp[now]));
}
else
{
if (trap[now]) for (int i = ; i<LIMIT; ++i) child_right[now][i] = tmp[now][i] = tmp[last][i - ];
else for (int i = ; i<LIMIT; ++i)child_right[now][i] = tmp[now][i] = tmp[last][i]; }for (int i = ; i<LIMIT; ++i)child_right[now][i] += arr[now]; long long ttmp[LIMIT]; memset(ttmp, , sizeof(ttmp));
for (int i = len - ; i >= ; --i)
{
int tar = G[now][i];
if (tar == last)continue;
for (int j = ; j<LIMIT; ++j)tmp[now][j] = max(tmp[now][j], ttmp[j]);
for (int j = ; j<LIMIT; ++j)tmp[now][j] += arr[now];
get_right(tar, now);
for (int j = ; j<LIMIT; ++j)tmp[now][j] -= arr[now];
if (trap[now]) for (int j = ; j<LIMIT; ++j)ttmp[j] = max(ttmp[j], child[tar][j - ]);
else for (int j = ; j<LIMIT; ++j) ttmp[j] = max(ttmp[j], child[tar][j]);
} } void init()
{
cin >> n >> c;
for (int i = ; i <= n; ++i)G[i].clear();
for (int i = ; i<n; ++i) cin >> arr[i] >> trap[i];
for (int i = ; i<n; ++i)
{
int a, b; cin >> a >> b;
G[a].push_back(b);
G[b].push_back(a);
}get_child(, -);
get_left(, -);
get_right(, -);
long long ans = ;
for (int i = ; i<n; ++i)
{
ans = max(ans, max(max(child_left[i][c], child_right[i][c]), child[i][c]));
}
cout << ans << endl;
}
int main()
{
cin.sync_with_stdio(false);
int tt; cin >> tt;
while (tt--)init(); return ;
}

HDU4616 树形DP+三次深搜的更多相关文章

  1. 【BZOJ-1060】时态同步 树形DP (DFS爆搜)

    1060: [ZJOI2007]时态同步 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2101  Solved: 595[Submit][Statu ...

  2. 树形dp——三色二叉树

    题目描述 一棵二叉树可以按照如下规则表示成一个由0.1.2组成的字符序列,我们称之为"二叉树序列S": 0 该树没有子节点 1S1 该树有一个子节点,S1为其二叉树序列 1S1S2 ...

  3. 深搜+DP剪枝 codevs 1047 邮票面值设计

    codevs 1047 邮票面值设计 1999年NOIP全国联赛提高组  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond 题目描述 Description ...

  4. P2668 斗地主 dp+深搜版

    题目描述 牛牛最近迷上了一种叫斗地主的扑克游戏.斗地主是一种使用黑桃.红心.梅花.方片的A到K加上大小王的共54张牌来进行的扑克牌游戏.在斗地主中,牌的大小关系根据牌的数码表示如下:3<4< ...

  5. 方格取数(多线程dp,深搜)

    https://www.luogu.org/problem/P1004 题目描述 设有N×N的方格图(N≤9),我们将其中的某些方格中填入正整数,而其他的方格中则放入数字0.如下图所示(见样例): 某 ...

  6. 【BZOJ-1864】三色二叉树 树形DP

    1864: [Zjoi2006]三色二叉树 Time Limit: 1 Sec  Memory Limit: 64 MBSubmit: 659  Solved: 469[Submit][Status] ...

  7. 【BZOJ1864】[Zjoi2006]三色二叉树 树形DP

    1864: [Zjoi2006]三色二叉树 Description Input 仅有一行,不超过500000个字符,表示一个二叉树序列. Output 输出文件也只有一行,包含两个数,依次表示最多和最 ...

  8. BZOJ_1864_[Zjoi2006]三色二叉树_树形DP

    BZOJ_1864_[Zjoi2006]三色二叉树_树形DP 题意: 分析:递归建树,然后DP,从子节点转移. 注意到红色和蓝色没有区别,因为我们可以将红蓝互换而方案是相同的.这样的话我们只需要知道当 ...

  9. 洛谷 P2585 [ ZJOI 2006 ] 三色二叉树 —— 树形DP

    题目:https://www.luogu.org/problemnew/show/P2585 首先,三色其实记录两种状态:是绿色,不是绿色 即可,因为红蓝可以随意取反: 一开始因为懒得还原出树,所以写 ...

随机推荐

  1. 寻找jar包的方法

    在项目开发中经常会遇到资源jar查找难的问题,一种使用maven ,另一种方法是: (1).使用下载地址:https://oss.sonatype.org/content/repositories/r ...

  2. magento新增商品属性以及将属性加入Flat table

    magento的EAV模型非常强大且灵活,但是如果不做优化的话,性能会非常低,因为attributes都存放在附表里,要获取一个entity的attribute,需要表联结一次,如果需要获取多条att ...

  3. mui的上拉下载和下拉刷新

    head部分(引入mui) <link href="./resources/css/mui.min.css" rel="stylesheet" /> ...

  4. Dll注入:注册表注入

    在系统中每一个进程加载User32.dll时,会受到DLL_PROCESS_ATTACH通知,当User32.dll对其进行处理时,会取得注册表键值HKEY_LOCAL_MACHINE\Softwar ...

  5. linux 命令——6 rmdir(转)

    今天学习一下linux中命令: rmdir命令.rmdir是常用的命令,该命令的功能是删除空目录,一个目录被删除之前必须是空的.(注意,rm - r dir命令可代替rmdir,但是有很大危险性.)删 ...

  6. 还在用SELECT COUNT统计数据库表的行数?Out了

    在ABAP里我们如果想用代码获得一个数据库表里有多少条记录,常规做法是使用SELECT COUNT. 如果您使用的是HANA数据库,现在有一种新的办法可以达到同样的目的.HANA数据库里有一张名为m_ ...

  7. Python开发第二篇

    运算符 1.算术运算符 % 取余运算符,返回余数 ** 幂运算符 //返回商的整数部分 2.逻辑运算符 and  与运算符 a and b 如果a为False是,表达式为False,如果a为True返 ...

  8. Windows底层开发前期学习准备工作

    1.若对Windows底层开发没有兴趣,不建议继续深究, 若有些兴趣可以继续. 2. 先广泛打基础,比如C/ASM/C++/MFC,再学习Windows核心编程,对R3上的一些开发有所熟悉,再系统的学 ...

  9. 实现Hbase的分页

    作者:R星月 出处:http://www.cnblogs.com/rxingyue 欢迎转载,也请保留这段声明.谢谢! 做一个项目中由于数据量比较大,并且需要定时增量分析,做了hbase的分页.项目中 ...

  10. 【BZOJ2242】[SDOI2011] 计算器(数学模板三合一)

    点此看题面 大致题意: 让你完成三种操作:求\(Y^Z\%P\)的值,求满足\(XY\equiv Z(mod\ P)\)的最小非负整数\(X\),求满足\(Y^X\equiv Z(mod\ P)\)的 ...