1. 程式人生 > >洛谷 P1270 “訪問”美術館(樹形DP)

洛谷 P1270 “訪問”美術館(樹形DP)

alt blog 經典 程序 span bsp 出了 準備 png

P1270 “訪問”美術館

題目描述

經過數月的精心準備,Peer Brelstet,一個出了名的盜畫者,準備開始他的下一個行動。藝術館的結構,每條走廊要麽分叉為兩條走廊,要麽通向一個展覽室。Peer知道每個展室裏藏畫的數量,並且他精確測量了通過每條走廊的時間。由於經驗老到,他拿下一幅畫需要5秒的時間。你的任務是編一個程序,計算在警察趕來之前,他最多能偷到多少幅畫。

技術分享

輸入輸出格式

輸入格式:

第1行是警察趕到的時間,以s為單位。第2行描述了藝術館的結構,是一串非負整數,成對地出現:每一對的第一個數是走過一條走廊的時間,第2個數是它末端的藏畫數量;如果第2個數是0,那麽說明這條走廊分叉為兩條另外的走廊。數據按照深度優先的次序給出,請看樣例。

一個展室最多有20幅畫。通過每個走廊的時間不超過20s。藝術館最多有100個展室。警察趕到的時間在10min以內。

輸出格式:

輸出偷到的畫的數量

輸入輸出樣例

輸入樣例#1:
60
7 0 8 0 3 1 14 2 10 0 12 4 6 2
輸出樣例#1:
2
思路:經典的樹形依賴DP,
dp[i][j]表示用j秒回到i最多拿幾幅畫。
錯因:題目說的是在警察來之前離開,所以它實際上只有tot-1秒。
#include<cstdio>
#include<cstring>
#include<iostream>
#include
<algorithm> using namespace std; int tot,n,dp[666][666]; void dfs(int root){ int time,pic; scanf("%d%d",&time,&pic); time*=2; if(!pic){ int lc=++n,rc=++n; dfs(lc);dfs(rc); for(int i=time;i<=tot;i++) for(int j=0;j<=i-time;j++) dp[root][i]
=max(dp[root][i],dp[lc][j]+dp[rc][i-time-j]); } else for(int i=time;i<=tot;i++) dp[root][i]=min((i-time)/5,pic); } int main() { scanf("%d",&tot); dfs(0); cout<<dp[0][tot-1]; }

洛谷 P1270 “訪問”美術館(樹形DP)