博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
树形动态规划
阅读量:4153 次
发布时间:2019-05-25

本文共 2174 字,大约阅读时间需要 7 分钟。

Description

有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点)
这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1。
我们用一根树枝两端连接的结点的编号来描述一根树枝的位置。下面是一颗有4个树枝的树
2 5
\ /
3 4
\ /
1
现在这颗树枝条太多了,需要剪枝。但是一些树枝上长有苹果。
给定需要保留的树枝数量,求出最多能留住多少苹果。

Input

第1行2个数,N和Q(1 <= Q <= N,1 < N <= 100)。
N表示树的结点数,Q表示要保留的树枝数量。接下来N-1行描述树枝的信息。
每行3个整数,前两个是它连接的结点的编号。第3个数是这根树枝上苹果的数量。
每根树枝上的苹果不超过30000个。

Output

一个数,最多能留住的苹果的数量。

Sample Input

5 2
1 3 1
1 4 10
2 3 20
3 5 20

Sample Output

21

分析:

这题的权值在边上,这在思考时有些别扭,其实只要把边的权值转移到儿子结点上,问题性质不变。

这样状态就应该容易想到了,f[i][j]表示以i结点为根的子树保留j个结点所得的最大值。因为根结点没有权值,所以我们要保留p+1个点。
f[i][j]=max{f[i_left][k]+f[i_right][j-1-k]}   (0<=k<=j-1)
边界 f[i][0]=0;f[i][1]=value[i]
最后f[1][p+1]就是答案

为什么是j-1-k,而不是j-k呢?这是因为要保留以i为根的j个节点,而i已经占了一个节点了,所以孩子节点只能再保留j-1个节点了。

#include
#include
#include
using namespace std;struct node{ int lc,rc; int s;} tree[220];int F[110][110],apple[110][110];bool vis[110];int n,q;void make_tree(int root)//一旦涉及到树的操作,递归总是会简化很多代码{//建立一颗二叉树 vis[root]=true; for (int i=1;i<=n;i++) if (!vis[i] && apple[root][i]!=-1) { if (tree[root].lc==0) tree[root].lc=i; else tree[root].rc=i; tree[i].s=apple[root][i]; make_tree(i); }}int tree_dp(int t,int k){ if (F[t][k]!=-1) return F[t][k]; if (t==0 || k==0) { F[t][k]=0; return 0; } F[t][k]=0; for (int i=0;i<=k-1;i++) {//递归左右孩子相加即为父亲最优值 int ls=tree_dp(tree[t].lc,i); int rs=tree_dp(tree[t].rc,k-1-i); if (F[t][k]

在建树的时候也可以和图算法类似:

#include 
#include
using namespace std;const int maxn=110;int N, Q;int u, v, w;int dp[maxn][maxn];struct Node{ int u, w;};vector
adj[maxn];void init( ){ for (int i=1; i<=N; i++) adj[i].clear(); for (int i=1; i
=0; j--) { for (int k=0; k+j+1<=left; k++) { dp[root][k+j+1] = max(dp[root][k+j+1], dp[u][k]+dp[root][j]+w); } } } } if (left==1) return;}int main( ){ while (cin>>N>>Q) { init( ); dfs(1, 1, Q); //root is 1 printf("%d\n", dp[1][Q]); } return 0;}
以上参考:

转载地址:http://tseti.baihongyu.com/

你可能感兴趣的文章
【Python】学习笔记——-7.0、面向对象编程
查看>>
【Python】学习笔记——-7.2、访问限制
查看>>
【Python】学习笔记——-7.3、继承和多态
查看>>
【Python】学习笔记——-7.5、实例属性和类属性
查看>>
git中文安装教程
查看>>
虚拟机 CentOS7/RedHat7/OracleLinux7 配置静态IP地址 Ping 物理机和互联网
查看>>
Jackson Tree Model Example
查看>>
常用js收集
查看>>
如何防止sql注入
查看>>
springmvc传值
查看>>
在Eclipse中查看Android源码
查看>>
Android使用webservice客户端实例
查看>>
[转]C语言printf
查看>>
C 语言学习 --设置文本框内容及进制转换
查看>>
C 语言 学习---ComboBox相关、简易“假”管理系统
查看>>
C 语言 学习---回调、时间定时更新程序
查看>>
第十一章 - 直接内存
查看>>
JDBC核心技术 - 上篇
查看>>
一篇搞懂Java反射机制
查看>>
Single Number II --出现一次的数(重)
查看>>