洛谷P1270 “访问”美术馆(树上背包)

题目链接

https://www.luogu.com.cn/problem/P1270

思路

我们定义 d p [ i ] [ j ] dp[i][j] dp[i][j]表示当前节点为 i i i,且背包容量为 j j j秒时所能偷走的画的最大值。

在进行状态转移的时候,如果当前节点是叶子节点,就判断能取多少。如果是分叉路口,就枚举分别分配给左右子树的时间来进行转移。

代码

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int>pii;
const int N = 6e3 + 5, M = 1e6 + 5;
const int mod = 998244353;
int n, cnt;
int dp[N][N];//当前节点为i用掉j秒能偷到的画的数量的最大值
void dfs()
{
	int root = ++cnt, time, num;
	cin >> time >> num;
	time <<= 1;
	if (num)
	{
		for (int i = time; i <= n; i++)
		{
			dp[root][i] = min(num, (i - time) / 5);
		}
	}
	else
	{
		int left = cnt + 1;
		dfs();
		int right = cnt + 1;
		dfs();
		for (int i = time; i <= n; i++)
		{
			for (int lr = 0; lr <= i - time; lr++)
			{
				dp[root][i] = max(dp[root][i], dp[left][lr] + dp[right][i - time - lr]);
			}
		}
	}
}
void solve()
{
	cin >> n;
	n--;
	dfs();
	cout << dp[1][n] << endl;
}

signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0), cout.tie(0);
	int test = 1;
	// cin >> test;
	for (int i = 1; i <= test; i++)
	{
		solve();
	}
	return 0;
}
相关推荐
王老师青少年编程19 小时前
2021信奥赛C++提高组csp-s复赛真题及题解:括号序列
c++·真题·信奥赛·csp-s·提高组·复赛·括号序列
追随者永远是胜利者19 小时前
(LeetCode-Hot100)32. 最长有效括号
java·算法·leetcode·职场和发展·go
lifallen19 小时前
CDQ 分治 (CDQ Divide and Conquer)
java·数据结构·算法
王老师青少年编程19 小时前
2021信奥赛C++提高组csp-s复赛真题及题解:回文
c++·真题·回文·信奥赛·csp-s·提高组·复赛
追随者永远是胜利者19 小时前
(LeetCode-Hot100)31. 下一个排列
java·算法·leetcode·职场和发展·go
ValhallaCoder19 小时前
hot100-二分查找
数据结构·python·算法·二分查找
0 0 019 小时前
【C++】矩阵翻转/n*n的矩阵旋转
c++·线性代数·算法·矩阵
sycmancia19 小时前
C++——类的真正形态、构造函数的调用
开发语言·c++
m0_5312371719 小时前
C语言-指针,结构体
c语言·数据结构·算法
癫狂的兔子20 小时前
【Python】【机器学习】十大算法简介与应用
python·算法·机器学习