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 
  • 相关阅读:
    java中清空session
    freemarker中修改和添加功能中包含checkbox复选框默认选中需求的解决方式
    Highcharts动态赋值学习
    CSDN Luncher
    JS导入导出Excel表格的方法
    js 下载文件的操作方法
    模板标签的作用
    css3的calc()
    JS滚轮mousewheel事件和DOMMouseScroll事件
    css BFC(格式化上下文)的理解
  • 原文地址:https://www.cnblogs.com/byluoluo/p/3383445.html
Copyright © 2011-2022 走看看