P1270 “访问”美术馆
一道简单的树形$dp$,但细节上要较为注意
$1.$ 递归读入
$2.$ $cst$数组要$*2$(因为要逃出)
$3.$ $m$ 要$-1$(严格小于)
令$f[u][j]$ 表示以$u$为根的子树用$j$秒所能获得的最大画数
如果不是二叉树,那么又是一个树上背包的模型,同样的思想转移
$$f[u][i] = max\left \{f[ls][j] + f[rs][i-cst[u]-j] \right \}$$
上代码
1 #include <iostream> 2 #include <algorithm> 3 #include <cstdio> 4 #include <cstring> 5 #define ll long long 6 using namespace std; 7 8 template <typename T> void in(T &x) { 9 x = 0; T f = 1; char ch = getchar(); 10 while(!isdigit(ch)) {if(ch == '-') f = -1; ch = getchar();} 11 while( isdigit(ch)) {x = 10 * x + ch - 48; ch = getchar();} 12 x *= f; 13 } 14 15 template <typename T> void out(T x) { 16 if(x < 0) x = -x , putchar('-'); 17 if(x > 9) out(x/10); 18 putchar(x%10 + 48); 19 } 20 //------------------------------------------------------- 21 22 const int N = 1001;//debug small 23 24 int m; 25 int sz[N],cst[N],w[N]; 26 int f[N][N]; 27 28 #define ls (u<<1) 29 #define rs (u<<1|1) 30 31 void rd(int u) { 32 in(cst[u]); in(w[u]); cst[u] <<= 1;//debug cst[u] <<= 1 -> w[u] <<= 1; 33 if(!w[u]) rd(ls),rd(rs); 34 } 35 36 void dfs(int u) { 37 int i,j; 38 if(w[u]) { 39 for(i = 1;i + cst[u] <= m && (i/5) <= w[u]; ++i) { 40 f[u][cst[u]+i] = i/5;//debug cst[u]+i -> i 41 } 42 return; 43 }//leaf 44 dfs(ls); dfs(rs);//debug -> not dfs 45 for(i = cst[u];i <= m; ++i) { 46 for(j = 0;j + cst[u] <= i; ++j) { 47 if(i-cst[u]-j) f[u][i] = max(f[u][i],f[ls][j] + f[rs][i-cst[u]-j]); 48 } 49 } 50 } 51 52 int main() { 53 in(m); --m; 54 rd(1); 55 dfs(1); 56 out(f[1][m]); 57 return 0; 58 }