码迷,mamicode.com
首页 > 其他好文 > 详细

题解 P1270 【“访问”美术馆】

时间:2020-06-11 20:04:20      阅读:55      评论:0      收藏:0      [点我收藏+]

标签:不用   有一个   fine   val   多叉树   编号   sum   typedef   size   

这道题明显的树形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\n",sum);
	return 0;
}

题解 P1270 【“访问”美术馆】

标签:不用   有一个   fine   val   多叉树   编号   sum   typedef   size   

原文地址:https://www.cnblogs.com/zdsrs060330/p/13095088.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!