这道题几经波折啊。

最开始和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. Sublime之插件的安装(一)

    由于最近刚换了一个工作,所以决定重新申请一个blog,把工作当中遇到的一些问题记录下来,方便自己下次忘记,也希望能与一起需要的小伙伴一起共勉. 如果有不同的观点或者是不同的看法,大家都可以畅谈,我一直 ...

  2. spring-boot 更换依赖版本

    创建Spring Boot操作步骤如下: 在File菜单里面选择 New > Project,然后选择Spring Initializr 更换版本 或 pom spring-boot-start ...

  3. BERT(Bidirectional Encoder Representations from Transformers)理解

    BERT的新语言表示模型,它代表Transformer的双向编码器表示.与最近的其他语言表示模型不同,BERT旨在通过联合调节所有层中的上下文来预先训练深度双向表示.因此,预训练的BERT表示可以通过 ...

  4. Mac OS X 编译android内核 error: elf.h: No such file or directory 的解决方法

    1. 从网上下个elf.h放到scripts/mod/文件夹(http://www.rockbox.org/tracker/9006?getfile=16683) 2. 修改两个文件mk_elfcon ...

  5. vue头像上传

    项目四知识点 默认头像 选择头像 <template> <div class="adatar"> <img :src="adatar?ada ...

  6. 让Linux应用更加得心应手的

    1.计算文件数和目录数  下面的语句可以帮你计算有多少个文件和多少个目录 # ls -l * |grep "^-"|wc -l ---- to count files # ls - ...

  7. Linux打补丁的一些问题

    linuxpatchlinux内核文档commandheader类unix操作系统有一个很有趣的特性就是源代码级的补丁包.在windows上我们打补丁都是运行一个可执行的程序,然后就可以把补丁打完了, ...

  8. java图片转byte转string

    第一种:原始乱码: public static void main(String[] args) throws IOException { File imgFile = new File(" ...

  9. requests 介绍

    一.  requests 参数 - method: 提交方式 - url: 提交地址 - params: 在URL中传递的参数,GET - data: 在请求体里传递的数据 - json 在请求体里传 ...

  10. csu 最优对称路径(bfs+记忆化搜索)

    1106: 最优对称路径 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 371  Solved: 77[Submit][Status][Web Boar ...