9月10日

来源:互联网 发布:忧伤的嫖客 知乎 编辑:程序博客网 时间:2024/05/17 07:22

1.树形DP入门题

地址:http://acm.hdu.edu.cn/showproblem.php?pid=1520

分析:树形DP题目,每个节点有权值,子节点和父节点不能同时选,问最后能选的最大价值是多少?

            状态方程为: dp[u][0] += max(dp[j][0], dp[j][1]), dp[u][1] += dp[j][0];   (0表示不选择u节点, 1表示选择该节点, j为u的子节点)

代码:

#include <iostream>#include <cstdio>#include <algorithm>#include <string>#include <cstring>#include <set>#include <utility>#include <map>#include <cstdlib>#include <queue>#include <vector>#include <numeric>#include <list>#include <bitset>#include <exception>#include <istream>#include <ostream>#include <stdexcept>#include <functional>#include <typeinfo>#define LL long long intusing namespace std;int val[6010];int dp[6010][2];vector<int> vec[6010];int in[6010];int dfs(int u){    dp[u][0] = 0, dp[u][1] = val[u];    for (int i = 0; i < vec[u].size(); ++i)    {        int j = vec[u][i];        dfs(j);        dp[u][0] += max(dp[j][0], dp[j][1]);        dp[u][1] += dp[j][0];    }    return max(dp[u][0], dp[u][1]);}int main(){    int n;    while (~scanf("%d", &n))    {        for (int i = 1; i <= n; ++i)            scanf("%d", &val[i]), vec[i].clear(), in[i] = 0;        int u, v;        while (scanf("%d%d", &u, &v) && u+v)        {            vec[v].push_back(u);            in[u]++;        }        int ans = 0;        for (int i = 1; i <=n; ++i)        {            if (in[i] == 0)            {                ans += dfs(i);                break;            }        }        printf("%d\n", ans);    }    return 0;}


0 0