HDOJ 1562 The more, The Better 树形DP 依赖背包

该程序是为了解决一个基于树结构的问题,通过深度优先搜索(DFS)和动态规划计算以特定节点为根的子树中,选择一定数量城堡所能获得的最大宝物数量。输入包含多组数据,每组数据表示一棵树的节点信息,输出是选取最多城堡时的最大宝物总数。
摘要由CSDN通过智能技术生成

🍑 OJ专栏


🍑 HDOJ 1562 The more, The Better

在这里插入图片描述
输入

3 2
0 1
0 2
0 3
7 4
2 2
0 1
0 4
2 1
7 1
7 6
2 2
0 0

输出

5
13

🙈 仿照大佬写的题解

🍑 AC

import java.util.*;

public class Main
{
	static int N = 210;
	static int[] v = new int[N];// 宝物数量(价值)数组
	static int[][] f = new int[N][N];// 表示以 i 为根节点 选择 j 个城堡攻击的 最大宝物数量

//	邻接表存树
	static ArrayList<Integer>[] list = new ArrayList[N];

	public static void main(String[] args)
	{
		Scanner sc = new Scanner(System.in);
		while (sc.hasNext())
		{
		  //  多组测试数据,记得初始化
			for (int i = 0; i < N; i++)
				for (int j = 0; j < N; j++)
					f[i][j] = 0;
			for (int i = 0; i < N; i++)
				list[i] = new ArrayList<Integer>();

			int n = sc.nextInt();
			int m = sc.nextInt();
			if (n == 0 && m == 0)
				break;

			for (int i = 1; i <= n; i++)
			{
				int a = sc.nextInt();
				v[i] = sc.nextInt();
				f[i][1] = v[i];
//				第 i 个城堡依赖于 城堡a 即 a --> i
				list[a].add(i);
			}
			dfs(0, m + 1);// 让 0 节点作为超级根节点
			System.out.println(f[0][m + 1]);
		}
	}

	private static void dfs(int x, int cnt)
	{
		int len = list[x].size();
		for (int i = 0; i < len; i++)//遍历当前树的所有子树
		{
    		int son = list[x].get(i);//某子树
			if (cnt > 1)// 一进来,只要当前树还能分,那就向下 递归
				dfs(son, cnt - 1);

			for (int v = cnt; v >= 2; v--)//枚举分给子节点的所有可能
				for (int j = 1; j < v; j++)// 根节点必须选,所以 j < v,留一个给根节点
					f[x][v] = Math.max(f[x][v], f[x][v - j] + f[son][j]);
		}
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值