P1270 “访问”美术馆

${\color{Cyan}{>>Question} }$

一道简单的树形$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 }

 

posted @ 2019-08-14 19:43  陈星卿  阅读(110)  评论(0编辑  收藏  举报