zoukankan      html  css  js  c++  java
  • 树形DP

    hdu1520

    题意:给定一棵关系树,每个节点有个权值,子节点和父节点不能同时选,问最后能选的最大价值是多少?

    点u有两个状态,选 - dp[u][1],不选 - dp[u][0]

    设v为儿子结点,则状态转移方程为:

    dp[u][1] = sum(dp[v][0])     说明:父节点选后,儿子节点都不能选

    dp[u][0] = sum( max(dp[v][0], dp[v][1]) )    说明:父节点不选时,子节点可选可不选,取决于值的大小 

    从叶子节点开始往根节点遍历,因此用dfs,在回溯阶段更新。

    /*
     *
     * 树形DP
     *
     
    */

    #include <iostream>
    #include <cstring>
    using namespace std;

    #define N 6010
    #define M 12010

    int head[N], eNum;
    struct Edge
    {
        int e, next;
    }edge[M];

    int dp[N][2], num[N];

    int max(int x, int y)
    {
        return x > y ? x : y;
    }

    void AddEdge(int u, int v)
    {
        edge[eNum].e = v;
        edge[eNum].next = head[u];
        head[u] = eNum++;
    }

    void dfs(int u, int fa)
    {
        //if(vis[u]) return ;
        
    //vis[u] = 1;
        for(int i = head[u]; i != -1; i = edge[i].next)
        {
            int v = edge[i].e;
            if(v == fa) continue;
            dfs(v, u);
            dp[u][1] += dp[v][0];
            dp[u][0] += max(dp[v][0], dp[v][1]);
        }
        dp[u][1] += num[u];
    }

    int main()
    {
        int n;
        while(cin >> n)
        {

        for(int i=1; i<=n; i++)
            cin >> num[i];
        memset(dp,0,sizeof(dp));
        memset(head,-1,sizeof(head));
        //memset(vis,0,sizeof(vis));
        eNum = 0;

        int u, v;
        while(cin >> u >> v)
        {
            if(u==0 && v==0)
                break;

            AddEdge(u, v);
            AddEdge(v, u);
        }
        dfs(10);
        cout << max(dp[1][0], dp[1][1]) << endl;
        }
        return 0;
    }


    /*
     *
     * 树形DP
     *
     
    */

    #include <iostream>
    #include <cstring>
    using namespace std;

    #define N 6010
    #define M 12010

    int head[N], eNum;
    struct Edge
    {
        int e, next;
    }edge[M];

    int dp[N][2], num[N];

    int max(int x, int y)
    {
        return x > y ? x : y;
    }

    void AddEdge(int u, int v)
    {
        edge[eNum].e = v;
        edge[eNum].next = head[u];
        head[u] = eNum++;
    }

    void dfs(int u, int fa)
    {
        //if(vis[u]) return ;
        
    //vis[u] = 1;
        for(int i = head[u]; i != -1; i = edge[i].next)
        {
            int v = edge[i].e;
            if(v == fa) continue;
            dfs(v, u);
            dp[u][1] += dp[v][0];
            dp[u][0] += max(dp[v][0], dp[v][1]);
        }
        dp[u][1] += num[u];
    }

    int main()
    {
        int n;
        while(cin >> n)
        {

        for(int i=1; i<=n; i++)
            cin >> num[i];
        memset(dp,0,sizeof(dp));
        memset(head,-1,sizeof(head));
        //memset(vis,0,sizeof(vis));
        eNum = 0;

        int u, v;
        while(cin >> u >> v)
        {
            if(u==0 && v==0)
                break;

            AddEdge(u, v);
            AddEdge(v, u);
        }
        dfs(10);
        cout << max(dp[1][0], dp[1][1]) << endl;
        }
        return 0;
    }
    View Code 
  • 相关阅读:
    LC.225. Implement Stack using Queues(using two queues)
    LC.232. Implement Queue using Stacks(use two stacks)
    sort numbers with two stacks(many duplicates)
    LC.154. Find Minimum in Rotated Sorted Array II
    LC.81. Search in Rotated Sorted Array II
    LC.35.Search Insert Position
    前后端分离:(一)
    Redis基本使用(一)
    GIT篇章(二)
    GIT篇章(一)
  • 原文地址:https://www.cnblogs.com/byluoluo/p/3383445.html
Copyright © 2011-2022 走看看