1. 程式人生 > >【樹上動規】【codevs 1163】訪問藝術館

【樹上動規】【codevs 1163】訪問藝術館

不用 tdi blog 復雜度 要花 clas 利用 第一個 數量

題目描述 Description
皮爾是一個出了名的盜畫者,他經過數月的精心準備,打算到藝術館盜畫。藝術館的結構,每條走廊要麽分叉為二條走廊,要麽通向一個展覽室。皮爾知道每個展室裏藏畫的數量,並且他精確地測量了通過每條走廊的時間,由於經驗老道,他拿下一副畫需要5秒的時間。你的任務是設計一個程序,計算在警察趕來之前(警察到達時皮爾回到了入口也算),他最多能偷到多少幅畫。

技術分享
輸入描述 Input Description
第1行是警察趕到得時間,以s為單位。第2行描述了藝術館得結構,是一串非負整數,成對地出現:每一對得第一個數是走過一條走廊得時間,第2個數是它末端得藏畫數量;如果第2個數是0,那麽說明這條走廊分叉為兩條另外得走廊。數據按照深度優先得次序給出,請看樣例
輸出描述 Output Description
輸出偷到得畫得數量
樣例輸入 Sample Input
60
7 0 8 0 3 1 14 2 10 0 12 4 6 2
樣例輸出 Sample Output
2
數據範圍及提示 Data Size & Hint
s<=600
走廊的數目<=100

f[i][j]表示在第i條走廊及其子樹上花費j時間能偷到的畫的數量

因為在當前走廊上要花費2*a的時間,所以留給子樹的時間就只有t-2*a

枚舉留給子樹的時間i,再枚舉其中一顆子樹的時間j

f[x][i+2*a]=max{f[l][j]+f[r][i-j]}

如果利用數據本身的DFS順序,就不用自己再建圖了,編程復雜度大大降低

 1 #include <cstdio>
 2 #include <iostream>
 3 using namespace std;
 4 int s,sz=0,f[100][601];
 5 int dfs(int t)
 6 {
 7     int
a,b,x=sz; 8 scanf("%d%d",&a,&b); 9 if (b) 10 { 11 for (int i=0;i<=t-2*a;i++) f[x][i+2*a]=min(i/5,b); 12 } 13 else 14 { 15 int l=++sz;dfs(t-2*a); 16 int r=++sz;dfs(t-2*a); 17 for (int i=0;i<=t-2*a;i++) 18 for (int j=0;j<=i;j++)
19 f[x][i+2*a]=max(f[x][i+2*a],f[l][j]+f[r][i-j]); 20 } 21 } 22 int main() 23 { 24 scanf("%d",&s); 25 dfs(s); 26 printf("%d",f[0][s]); 27 }

【樹上動規】【codevs 1163】訪問藝術館