[POJ1155]TELE(树形dp)
来源:互联网 发布:java 乘法溢出 编辑:程序博客网 时间:2024/06/06 12:24
题目描述
传送门
题解
size[i]表示以i为根的子树中有几个叶子节点。
f[i][j]表示以i为根的子树中,选j个叶子节点的最大收益。
那么f[x][j+k]=max(f[x][j+k],last[j]+f[v[i]][k]-c[i]);
注意现在更新的状态用的原始的状态不能是刚更新过的状态,所以要用一个last数组来存之前的状态然后更新。
代码
#include<iostream>#include<cstring>#include<cstdio>using namespace std;const int max_n=3e3+5;const int max_e=max_n*2;const int INF=2e9;int n,m,k,x,y;int f[max_n][max_n],size[max_n],last[max_n];int tot,next[max_e],point[max_n],v[max_e],c[max_e];inline void add(int x,int y,int z){++tot;next[tot]=point[x];point[x]=tot;v[tot]=y;c[tot]=z;}inline void treedp(int x,int fa){ for (int i=point[x];i;i=next[i]) if (v[i]!=fa){ treedp(v[i],x); for (int j=0;j<=size[x];++j) last[j]=f[x][j]; for (int j=0;j<=size[x];++j) for (int k=1;k<=size[v[i]];++k) f[x][j+k]=max(f[x][j+k],last[j]+f[v[i]][k]-c[i]); size[x]+=size[v[i]]; }}int main(){ scanf("%d%d",&n,&m); for (int i=1;i<=n-m;++i){ scanf("%d",&k); for (int j=1;j<=k;++j){ scanf("%d%d",&x,&y); add(i,x,y),add(x,i,y); } } for (int i=1;i<=n;++i) for (int j=1;j<=n;++j) f[i][j]=-INF; memset(size,0,sizeof(size)); for (int i=n-m+1;i<=n;++i) scanf("%d",&f[i][1]),size[i]=1; treedp(1,0); for (int i=m;i>=0;--i) if (f[1][i]>=0){ printf("%d\n",i); return 0; }}
总结
自己感觉到了之前树形背包的坑在哪里。。
大概就是状态的问题,现在更新的状态用的原始的状态不能是刚更新过的状态。
0 0
- POJ1155 TELE(树形DP)
- [POJ1155]TELE(树形dp)
- [POJ1155]TELE(树形dp)
- POJ1155:TELE(树形DP)
- poj1155 TELE 【树形dp】
- poj1155 TELE(树形dp)
- POJ1155---TELE(树形dp,背包)
- poj1155 TELE(树形dp+背包)
- poj1155 TELE(树形+背包dp)
- POJ1155 TELE【树形dp(背包)】
- [poj1155] TELE 树形DP 01背包
- poj1155 (树形dp)
- POJ1155 TELE(树DP)
- TELE(树形dp+背包)
- poj1155之树形DP
- poj1155(树形dp)
- poj1155树形dp+背包
- poj1155(树形dp)
- <Android 应用 之路> 天气预报(三)
- 1010
- Java中的private、protected、public和default的区别
- java并发编程(13)--线程间协作的两种方式:wait、notify、notifyAll和Condition
- Java使用UDP协议编写聊天程序
- [POJ1155]TELE(树形dp)
- 数据库建表时字段长度
- FFMPEG
- 环信sdk与支付宝的冲突
- Session监听
- 对MobSF的源码进行分析
- 模拟BootStrap的弹框功能
- C#连接数据库的方法
- 利用curand的host API生成均匀分布的随机数