题解 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 “访问”美术馆的主要内容,如果未能解决你的问题,请参考以下文章