在树上跑dp;一般都是dfs和bfs,有点像记忆化,向子树要答案,然后可以向上返回,在递归的过程中去dp,,与前面的dp类似,不同的是递归过程中跑dp;
1 int dfs(int x){ 2 if (x > n - m){ 3 f[x][1] = v[x]; 4 return 1; 5 } 6 int ret = 0; 7 for (int k = first[x]; k; k = e[k].next){ 8 int to = e[k].to; 9 int t = dfs(to); 10 ret += t; 11 for (int j = ret; j > 0; --j){ 12 for (int i = 1; i <=min(j,t); ++i){ 13 f[x][j] = max(f[x][j], f[x][j-i] + f[to][i] - e[k].w); 14 } 15 } 16 } 17 return ret; 18 }
//这是洛谷p1273与这类似
树上背包
无依赖关系
int n,m; vector<int>son[N]; int f[1010][1010]; int val[1010]; void dfs(int x) { for (int a : son[x]) { dfs(a); for (int j = m; j >= 0; --j) { for (int k = 0; k <= j; ++k) { f[x][j] = max(f[x][j], f[x][j - k]+f[a][k]+val[x]); } } } }
有依赖关系
选子必须选父
int n,m; vector<int>son[N]; int f[1010][1010]; int val[1010]; void dfs(int x) { f[x][1] = val[x]; for (int j = 2; j <= m; ++j) { f[x][j] = f[x][j - 1]; } for (int a : son[x]) { dfs(a); for (int j = m; j >= 0; --j) { for (int k = 0; k <= j; ++k) { f[x][j] = max(f[x][j], f[x][j - k]+f[a][k]); } } } }
浙公网安备 33010602011771号