题解 P1270 “访问”美术馆

Posted zdsrs060330

tags:

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

这道题明显的树形DP,但是我有一个邪恶的想法,让他变成多叉树,而且不用返回可以幻影移形,但是得走回来才能去另一条走廊。这看起来很恶毒,我也不知道怎么做。

做法大家都解释的差不多了,这里我主要说一下毒瘤的读入

这道题的读入与这篇博客所讲的题目的输入非常相似

void init(int &x){
	x=++tot;
	if(m[x][1]==0){
		val[x]=m[x][0]*2;
		init(c[x][0]);init(c[x][1]);
	} 
	else val[x]=m[x][0]*2,pic[x]=m[x][1];
	return;
}

一开始

主要就是dp[u][tim],u为点的编号,tim为分配给这个点及其子树的时间,

枚举k为1->tim

dp[u][tim]=max(dp[u][tim],dp[c[u][0]][k]+dp[c[u][1]][tim-k]);

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define debug printf("*");
//#define mo 1e9+7
const int N=110;
int tot,e,t,rt;
int c[N][2],m[N][2],val[N],pic[N],dp[N][610];
void init(int &x){
	x=++tot;
	if(m[x][1]==0){
		val[x]=m[x][0]*2;
		init(c[x][0]);init(c[x][1]);
	} 
	else val[x]=m[x][0]*2,pic[x]=m[x][1];
	return;
}
int dfs(int u,int tim){
	int v1=c[u][0],v2=c[u][1];
	if(dp[u][tim]!=-1) return dp[u][tim];
	if(tim<=val[u]) return dp[u][tim]=0;
	tim-=val[u];
	int ans=0;
	if(m[u][1]==0){
		for(int i=0;i<=tim;i++)
			ans=max(ans,dfs(v1,i)+dfs(v2,tim-i));
	} else{
		ans=min(tim/5,pic[u]);
	}
	dp[u][tim+val[u]]=ans;
	return ans;
}
int main(){
	memset(dp,-1,sizeof(dp));
	scanf("%d",&t);
	e=1;
	while(scanf("%d %d",&m[e][0],&m[e][1])==2) e++;
	init(rt);
	int sum=0;
	for(int i=0;i<t;i++)
		sum=max(sum,dfs(rt,i));
	printf("%d
",sum);
	return 0;
}

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

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

P1270 “访问”美术馆

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

P1270 “访问”美术馆

luogu P1270 "访问"美术馆 树dp

1163 访问艺术馆