P1270 “访问”美术馆(树形dp)

Posted Harris-H

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P1270 “访问”美术馆(树形dp)相关的知识,希望对你有一定的参考价值。

P1270 “访问”美术馆(树形dp)

依题意可知,该模型为一个二叉树。

每个结点有两个属性(经过时间,画的个数)。

因为必须要回到根来,考虑树形dp。

先把每个结点的时间乘以2,因为要保证能回来。

然后令 d p ( u , s u m ) dp(u,sum) dp(u,sum)表示当前子树剩下 s u m sum sum的时间的答案。

然后就可以记忆化搜索实现dp,枚举左子树分配的时间 t ∈ [ 0 , s u m − a [ u ] . t i m e ] t\\in [0,sum-a[u].time] t[0,suma[u].time]

m a x ( d p ( u , s u m ) , d p ( l s o n , i ) + d p ( r s o n , s u m − i − a [ u ] . t i m e ) ) max(dp(u,sum),dp(lson,i)+dp(rson,sum-i-a[u].time)) max(dp(u,sum),dp(lson,i)+dp(rson,sumia[u].time))

时间复杂度: O ( c n t ) O(cnt) O(cnt) c n t cnt cnt为结点数。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull; 
const int N=1e3+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
const int hashmod[4] = 402653189,805306457,1610612741,998244353;
#define mst(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define PLL pair<ll,ll>
#define x first
#define y second
#define pb emplace_back
#define SZ(a) (int)a.size()
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define per(i,a,b) for(int i=a;i>=b;--i)
#define ios ios::sync_with_stdio(false),cin.tie(nullptr) 
void Print(int *a,int n)
	for(int i=1;i<n;i++)
		printf("%d ",a[i]);
	printf("%d\\n",a[n]); 

template <typename T>
void cmx(T &x,T y)
	if(x<y) x=y;

template <typename T>
void cmn(T &x,T y)
	if(x>y) x=y;

PII a[N];
void dfs(int rt)
	scanf("%d%d",&a[rt].x,&a[rt].y);a[rt].x<<=1;
	if(!a[rt].y)
		dfs(rt<<1);
		dfs(rt<<1|1);
	

int f[N][N];
int fun(int rt,int s)
	if(f[rt][s]>0 || !s) return f[rt][s];
	if(a[rt].y) return min(a[rt].y,(s-a[rt].x)/5);
	for(int i=0;i<=s-a[rt].x;i++)
		cmx(f[rt][s],fun(rt<<1,i)+fun(rt<<1|1,s-a[rt].x-i));
	return f[rt][s];

int main()
	int s;scanf("%d",&s);
	dfs(1);
	printf("%d\\n",fun(1,s-1));
	return 0;


以上是关于P1270 “访问”美术馆(树形dp)的主要内容,如果未能解决你的问题,请参考以下文章

洛谷 P1270 “访问”美术馆(树形DP)

P1270 “访问”美术馆

luogu P1270 "访问"美术馆 树dp

题解 P1270 “访问”美术馆

P1270 “访问”美术馆

luogu1270 “访问”美术馆 树形dp