HDU 1561  The more, The Better

题目大意就不说了

直接DP[i][j]表示i为跟节点的子树上攻克j个城堡的所能获得的最多宝物的数量

DP[fa][j] = MAX{DP[fa][i-k] + DP[child][k]};

首先一个问题就是说如果子树u下的任意子节点被选择了,那么u是一定需要选择的,怎么在DP时保证准确性,其实这个很好解决,我们在计算时是需要枚举k(子节点的攻克数量)的,那么我们迫使k<j就可以了,这样的话DP[fa][j] 就不会被子节点的DP[child][j]更新掉保证了他的父节点一定在被选择的里面

另外一个问题就是如果枚举j时是从小到达枚举,那么DP[fa][j]很可能已经被当前的child更新过了,那么在计算DP[fa][j+1]或者以后时,很可能有会被放入同一个child,导致当前的child被选择了多次,所以我们需要逆序枚举j(k的顺序无关紧要了)

最后的结果就是个棵树上同样取DP值,只是一颗完整的树上可以一个也不取了

 #include <map>
#include <set>
#include <stack>
#include <queue>
#include <cmath>
#include <ctime>
#include <vector>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
#define INF ((LL)100000000000000000)
#define inf (-((LL)1<<40))
#define lson k<<1, L, mid
#define rson k<<1|1, mid+1, R
#define mem0(a) memset(a,0,sizeof(a))
#define mem1(a) memset(a,-1,sizeof(a))
#define mem(a, b) memset(a, b, sizeof(a))
#define FOPENIN(IN) freopen(IN, "r", stdin)
#define FOPENOUT(OUT) freopen(OUT, "w", stdout)
template<class T> T CMP_MIN(T a, T b) { return a < b; }
template<class T> T CMP_MAX(T a, T b) { return a > b; }
template<class T> T MAX(T a, T b) { return a > b ? a : b; }
template<class T> T MIN(T a, T b) { return a < b ? a : b; }
template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; }
template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b; } //typedef __int64 LL;
typedef long long LL;
const int MAXN = ;
const int MAXM = ;
const double eps = 1e-;
int dx[] = {-, , , };
int dy[] = {, -, , }; int N, M;
int G[MAXN][MAXN], vis[MAXN], num[MAXN];
int DP[MAXN][MAXN], D[MAXN]; void DFS(int u)
{
vis[u] = ;
DP[u][] = num[u];
for(int i=;i<=N;i++) if(G[u][i])
{
if(!vis[i]) DFS(i);
for(int j=M;j>;j--)//这里为了保证是先从父节点更新,需要逆序
for(int k=;k<j;k++)//k<j保证父节点不会被更新掉
DP[u][j] = MAX(DP[u][j], DP[u][j-k] + DP[i][k]);
}
} int main()
{
//FOPENIN("in.txt");
while(~scanf("%d %d", &N, &M) &&( N||M))
{
int a;mem0(G);mem0(D);mem0(vis);mem0(DP);
for(int i=;i<=N;i++) {
scanf("%d %d", &a, &num[i]);
if(a != )G[a][i] = ;
else D[i] = ;
}
for(int i=;i<=N;i++) if(!vis[i]){
DFS(i);
if(D[i]) for(int j=M;j>=;j--)//同样需要逆序,可以取到0
{
for(int k=;k<=j;k++)
DP[][j] = MAX(DP[][j], DP[][j-k] + DP[i][k]);
}
}
printf("%d\n", DP[][M]); }
return ;
}

HDU 1561The more, The Better(树形DP)的更多相关文章

  1. hdu 4514 并查集+树形dp

    湫湫系列故事——设计风景线 Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Tot ...

  2. [HDU 5293]Tree chain problem(树形dp+树链剖分)

    [HDU 5293]Tree chain problem(树形dp+树链剖分) 题面 在一棵树中,给出若干条链和链的权值,求选取不相交的链使得权值和最大. 分析 考虑树形dp,dp[x]表示以x为子树 ...

  3. HDU 5293 Tree chain problem 树形dp+dfs序+树状数组+LCA

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5293 题意: 给你一些链,每条链都有自己的价值,求不相交不重合的链能够组成的最大价值. 题解: 树形 ...

  4. hdu 4003 Find Metal Mineral 树形DP

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4003 Humans have discovered a kind of new metal miner ...

  5. HDU 5758 Explorer Bo(树形DP)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5758 [题目大意] 给出一棵树,每条路长度为1,允许从一个节点传送到任意一个节点,现在要求在传送次 ...

  6. 2017 Multi-University Training Contest - Team 1 1003&&HDU 6035 Colorful Tree【树形dp】

    Colorful Tree Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)T ...

  7. HDU 4123 Bob’s Race 树形dp+单调队列

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4123 Time Limit: 5000/2000 MS (Java/Others) Memory L ...

  8. HDU 4799 LIKE vs CANDLE 树形dp

    题意:有n个人,他们的关系,形成一棵有根树(0是树根,代表管理员),每个人有一个价值 现在有一条微博,每个人要么点赞,要么送一个蜡烛 初始一些人利用bug反转了某些人的操作(赞变蜡烛 或者 蜡烛变成赞 ...

  9. hdu 3586 Information Disturbing(树形dp + 二分)

    本文出自   http://blog.csdn.net/shuangde800 题目链接:   hdu-3586 题意 给一棵n个节点的树,节点编号为1-n,根节点为1.每条边有权值,砍掉一条边要花费 ...

  10. HDU 1054 Strategic Game(树形DP)

    Problem Description Bob enjoys playing computer games, especially strategic games, but sometimes he ...

随机推荐

  1. Codeforces 447 C DZY Loves Sequences【DP】

    题意:给出一列数,在这个序列里面找到一个连续的严格上升的子串,现在可以任意修改序列里面的一个数,问得到的子串最长是多少 看的题解,自己没有想出来 假设修改的是a[i],那么有三种情况, 1.a[i]& ...

  2. 学习java之泛型类和泛型方法

    上一篇博文中我自己试着用了下泛型类,昨天看java编程思想一书,发现里面有这么一段话: 使用参数化方法而不是用参数化类的方便之处在于:你不必为需要应用的每种不同类型都使用一个参数去实例化这个类,并且你 ...

  3. python练习程序(c100经典例6)

    题目: 用*号输出字母C的图案. print "***" print "*" print "*" print "***"

  4. 【Java】MD5加密

    package sdfg; import java.math.BigInteger; import java.security.MessageDigest; import java.security. ...

  5. python编码问题(1)

    一.字符编码基础 字符编码是计算机对字符的格式化,从而能够在计算机系统中存储与传输. 1.ASCII码 在计算机内部,所有的信息最终都表示为一个二进制的字符串.每一个二进制位(bit)有0和1两种状态 ...

  6. ecshop lib包含lib文件

    在lbi文件中增加lbi方法 方法1. {include file='library/name.lbi '} 方法2. <?php echo $this->fetch('library/n ...

  7. aspose调用打印机打印文档

    aspose很不错的插件,功能非常强大,用到了其中的aspose.word. 如何生成word文档,点击. 下面说说如何如何通过打印机打印文档. aspose提供了一个print方法,通过该方法可以直 ...

  8. 聊聊Dataguard的三种保护模式实验(上)

    Data Guard是Oracle高可用性HA的重要解决方案.针对不同的系统保护需求,DG提供了三种不同类型的保护模式(Protection Mode),分别为:最大保护(Maximum Protec ...

  9. 不可或缺的 sendEmail

    还在为Linux下没有便捷的邮件程序苦恼,还在为复杂的邮件服务器架设Google N多网页? 对于小型,便捷的Linux下命令行邮件程序,sendEmail使得这一切变得轻松可行.一起来看看吧. 一. ...

  10. 深入学习Struts2

    本部分主要介绍struts.xml的常用配置. 1.1.    包配置: Struts2框架中核心组件就是Action.拦截器等,Struts2框架使用包来管理Action和拦截器等.每个包就是多个A ...