1. 程式人生 > 實用技巧 >P1270 “訪問”美術館 題解

P1270 “訪問”美術館 題解

Link

P1270 “訪問”美術館

solve

這道題給出的結構都是樹形的,所以很容易就看出是樹形DP,我們定義\(F[i][j]\)表示走到第i條邊,還有j秒時間能拿的最大畫數,對於盡頭是展室的能拿則拿,盡頭是走廊的我們列舉分到不同走廊的時間,用記憶化DFS來實現就好了。

code

#include<bits/stdc++.h>
using namespace std;
const int maxn=1005;
int Tim,cost[maxn*10],val[maxn*10],F[maxn][maxn];
inline int read(){
	int ret=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-f;ch=getchar();}
	while(ch<='9'&&ch>='0')ret=ret*10+ch-'0',ch=getchar();
	return ret*f;
}
void init(int x){
	cost[x]=read()*2,val[x]=read();
	if(!val[x]){init(x<<1);init(x<<1|1);}
}
int max(int a,int b){return a>b?a:b;}
int min(int a,int b){return a<b?a:b;}
int DFS(int x,int tim){
	if(F[x][tim]>0||tim==0)return F[x][tim];
	if(val[x])return F[x][tim]=min(val[x],(tim-cost[x])/5);
	for(int i=0;i<=tim-cost[x];i++){
		F[x][tim]=max(F[x][tim],DFS(x<<1,i)+DFS(x<<1|1,tim-cost[x]-i));
	}
	return F[x][tim];
}
int main(){
	freopen("P1270.in","r",stdin);
	freopen("P1270.out","w",stdout);
	Tim=read()-1;
	init(1);
	printf("%d\n",DFS(1,Tim));
	return 0;
}