• 洛谷1273(树上分组背包)


    要点

    • 扫每个儿子时更新一次dp
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <vector>
    using namespace std;
    
    const int maxn = 3005;
    int n, m, Cost[maxn];
    int f[maxn][maxn], size[maxn];
    vector<pair<int, int>> adj[maxn];
    
    void dfs(int u) {
    	if (u > n - m) {//叶子
    		size[u] = 1;
    		f[u][1] = Cost[u];
    	}
    	f[u][0] = 0;
    	for (auto son : adj[u]) {
    		int v = son.first, c = son.second;
    		dfs(v);
    		size[u] += size[v];
    		for (int j = size[u]; j; j--) {//必须倒序,背包其实省略了一维[i]
    			for (int k = 0; k <= min(j, size[v]); k++) {//当前子树选几个
    				f[u][j] = max(f[u][j], f[v][k] + f[u][j - k] - c);
    			}
    		}
    	}
    }
    
    int main() {
    	scanf("%d %d", &n, &m);
    	for (int u = 1, k, v, cost; u <= n - m; u++) {//建图
    		for (scanf("%d", &k); k; k--) {
    			scanf("%d %d", &v, &cost);
    			adj[u].emplace_back(v, cost);
    		}
    	}
    	for (int u = n - m + 1; u <= n; u++) {//叶子的值
    		scanf("%d", &Cost[u]);
    	}
    
    	memset(f, 0xcf, sizeof f);//-inf
    	dfs(1);
    	for (int i = n; ~i; --i)
    		if (f[1][i] >= 0) {//不亏本
    			printf("%d
    ", i);
    			break;
    		}
    }
    
  • 相关阅读:
    array_unshift() 、
    readfile() 函数
    Java的异常处理
    Java 接口
    Java 抽象类
    final关键字
    statice关键字
    dom查询
    JS 正则表达式
    JS对象
  • 原文地址:https://www.cnblogs.com/AlphaWA/p/10998172.html
Copyright © 2020-2023  润新知