这道题几经波折啊。

最开始和vfleaking一样,把题意理解错了,认为一个装备可能被多个装备依赖,然后想不出来,去看题解。

发现自己理解错了题意,自己想想,其实也不难想到dp[i][j][k]表示“i号节点代表的子树,用掉j的钱,给父亲预留k个自己(但还是父亲付钱)”的状态,写出来交上去就是T,

开始以为是常数问题,优化半天还是T,看了他人AC代码,才发现自己算法有一定问题:重复计算了很多东西。

树形动规,一般在大的树规下,每个节点还会对儿子们来一次”资源分配“,一般是用背包解决,这道题也是这样,但又有一点不一样,就是我们也要给该子树的根节点本身分配资源,

我就是这儿重复计算了,对于所有儿子的同一k,我算了多次。

 /**************************************************************
Problem: 1017
User: idy002
Language: C++
Result: Accepted
Time:16524 ms
Memory:48316 kb
****************************************************************/ #include <cstdio>
#include <cstring>
#include <vector>
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define maxn 55
#define maxm 2010
#define maxl 110
#define oo 0x3f3f3f3f
using namespace std; int n, m;
int indgr[maxn];
int power[maxn], cost[maxn], limit[maxn];
int head[maxn], next[maxn], dest[maxn], wght[maxn], tot; int dp[maxn][maxm][maxl];
int ep[maxm]; void insert( int a, int b, int w ) {
tot++;
wght[tot] = w;
dest[tot] = b;
next[tot] = head[a];
head[a] = tot;
}
void dfs( int i ) {
if( !head[i] ) return;
cost[i] = ;
limit[i] = oo; for( int t=head[i]; t; t=next[t] ) {
int s = dest[t], w = wght[t];
dfs( s );
cost[i] += cost[s]*w;
limit[i] = min( limit[i], limit[s]/w );
}
} void dodp( int i ) {
if( !head[i] ) {
for( int l=; l<=limit[i]; l++ )
for( int k=l; k>=; k-- ) {
int self = (l-k);
int j = self*cost[i];
if( j>m ) break;
dp[i][j][k] = self*power[i];
}
return;
}
for( int t=head[i]; t; t=next[t] )
dodp( dest[t] );
for( int l=; l<=limit[i]; l++ ) {
for( int j=; j<=m; j++ ) ep[j]=;
for( int t=head[i]; t; t=next[t] ) {
int v = dest[t], w = wght[t];
int vl = l*w;
for( int j=m; j>=; j-- )
for( int jj=; jj<=j; jj++ )
ep[j] = max( ep[j], ep[j-jj]+dp[v][jj][vl] );
}
for( int j=; j<=m; j++ )
for( int k=l; k>=; k-- ) {
int self = l-k;
int remain = j- self*cost[i];
if( remain< ) break;
dp[i][j][k] = max( dp[i][j][k], ep[remain]+self*power[i] );
}
}
} int main() {
scanf( "%d%d", &n, &m );
for( int i=; i<=n; i++ ) {
char type[];
scanf( "%d%s", power+i, type );
if( type[]=='A' ) {
int cnt;
scanf( "%d", &cnt );
for( int t=,c,w; t<=cnt; t++ ) {
scanf( "%d%d", &c, &w );
insert( i, c, w );
indgr[c]++;
}
} else
scanf( "%d%d", cost+i, limit+i );
}
int root = ;
for( int i=; i<=n; i++ )
if( indgr[i]== ) {
root = i;
break;
}
memset( dp, , sizeof(dp) );
dfs(root);
dodp(root);
int ans = ;
for( int j=; j<=m; j++ ) ans = max( ans, dp[root][j][] );
printf( "%d\n", ans );
}

bzoj 1017 tree dp的更多相关文章

  1. bzoj 2212 Tree Rotations

    bzoj 2212 Tree Rotations 考虑一个子树 \(x\) 的左右儿子分别为 \(ls,rs\) .那么子树 \(x\) 内的逆序对数就是 \(ls\) 内的逆序对数,\(rs\) 内 ...

  2. 96. Unique Binary Search Trees (Tree; DP)

    Given n, how many structurally unique BST's (binary search trees) that store values 1...n? For examp ...

  3. HDU 4359——Easy Tree DP?——————【dp+组合计数】

    Easy Tree DP? Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)To ...

  4. TYOI Day1 travel:Tree dp【处理重复走边】

    题意: 给你一棵树,n个节点,每条边有长度. 然后有q组询问(u,k),每次问你:从节点u出发,走到某个节点的距离mod k的最大值. 题解: 对于无根树上的dp,一般都是先转成以1为根的有根树,然后 ...

  5. HDU 4359 Easy Tree DP?

    Easy Tree DP? Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)To ...

  6. bzoj 1017: [JSOI2008]魔兽地图DotR【树形dp+背包】

    bzoj上是一个森林啊--? dp还是太弱了 设f[i][j][k]为到点i,合成j个i并且花费k金币能获得的最大力量值,a[i]为数量上限,b[i]为价格,p[i]为装备力量值 其实这个状态设计出来 ...

  7. BZOJ 1017 魔兽地图DotR(树形DP)

    题意:有两类装备,高级装备A和基础装备B.现在有m的钱.每种B有一个单价和可以购买的数量上限.每个Ai可以由Ci种其他物品合成,给出Ci种其他物品每种需要的数量.每个装备有一个贡献值.求最大的贡献值. ...

  8. BZOJ.1017.[JSOI2008]魔兽地图(树形DP 背包DP)

    题目链接 树形DP,考虑子节点对父节点的贡献. 设f[x][i][j]表示当前为x,用i个x去合成上一层装备,花费为j的最大价值. 由子节点转移时 是一个分组背包,需要一个辅助数组g[i][j]表示前 ...

  9. BZOJ 2111 [ZJOI2010]Perm 排列计数:Tree dp + Lucas定理

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2111 题意: 给定n,p,问你有多少个1到n的排列P,对于任意整数i∈[2,n]满足P[i ...

随机推荐

  1. TensorFlow下利用MNIST训练模型识别手写数字

    本文将参考TensorFlow中文社区官方文档使用mnist数据集训练一个多层卷积神经网络(LeNet5网络),并利用所训练的模型识别自己手写数字. 训练MNIST数据集,并保存训练模型 # Pyth ...

  2. 关于一些对location认识的误区

    1. location 的匹配顺序是“先匹配正则,再匹配普通”. 矫正: location 的匹配顺序其实是“先匹配普通,再匹配正则”.我这么说,大家一定会反驳我,因为按“先匹配普通,再匹配正则”解释 ...

  3. 微信开发,调用js-SDK接口

    微信开发,调用js-SDK接口<!DOCTYPE html><html><head lang="en"> <meta charset=&q ...

  4. PCA算法和SVD

    如果矩阵对某一个向量或某些向量只发生伸缩变换,不对这些向量产生旋转的效果,那么这些向量就称为这个矩阵的特征向量,伸缩的比例就是特征值.这里可以将特征值为负,特征向量旋转180度,也可看成方向不变,伸缩 ...

  5. Photon3Unity3D.dll 解析二——EventData

    EventData 包含Photon事件的所有内容 Code           用于表示事件,相当于主键ID,LiteEventCode定义了一部分服务端普遍事件事件: Parameters   事 ...

  6. 数据库介绍及MySQL安装

    阅读目录 一.数据库是什么? 二.数据库特点 三. 什么是数据库管理系统(DataBase Management System 简称DBMS) 四.数据库服务器.数据管理系统.数据库.表与记录的关系( ...

  7. 深度学习方法(十二):卷积神经网络结构变化——Spatial Transformer Networks

    欢迎转载,转载请注明:本文出自Bin的专栏blog.csdn.net/xbinworld. 技术交流QQ群:433250724,欢迎对算法.机器学习技术感兴趣的同学加入. 今天具体介绍一个Google ...

  8. email的传输协议与格式(资源链接)

    以下链接为转载. 传输协议: 发:SMTP 收:POP3, IMAP 格式: MIME

  9. jmeter-----查看结果树

    在编写接口测试脚本的时候,需要进行调试和查看结果是否正常的情况,这个时候可以使用查看结果树组件进行. 查看结果树中展示了每一个取样器的结果.请求信息和响应信息,可以查看这些内容去分析脚本是否存在问题. ...

  10. IEEEXtreme 10.0 - Always Be In Control

    这是 meelo 原创的 IEEEXtreme极限编程大赛题解 Xtreme 10.0 - Always Be In Control 题目来源 第10届IEEE极限编程大赛 https://www.h ...