zoukankan      html  css  js  c++  java
  • 树型DP入门

    题意:
    某公司要举办一次晚会,但是为了使得晚会的气氛更加活跃,每个参加晚会的人都不希望在晚会中见到他的直接上司,现在已知每个人的活跃指数和上司关系(当然不可能存在环),求邀请哪些人(多少人)来能使得晚会的总活跃指数最大。

    思路:
    任何一个点的取舍可以看作一种决策,那么状态就是在某个点取的时候或者不取的时候,以他为根的子树能有的最大活跃总值。分别可以用f[i,1]和f[i,0]表示第i个人来和不来。

    当i来的时候,dp[i][1] += dp[j][0];//j为i的下属
    当i不来的时候,dp[i][0] +=max(dp[j][1],dp[j][0]);//j为i的下属

    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    using namespace std;
    
    int father[6005],vis[6005],dp[6005][2],t;
    
    void dfs(int node)
    {
        int i,j;
        vis[node] = 1;
        for(i = 1;i<=t;i++)
        {
           if(!vis[i] && father[i] == node)
           {
               dfs(i);
               dp[node][1]+=dp[i][0];//node去,则i必不能去
               dp[node][0]+=max(dp[i][0],dp[i][1]);//node不去,取i去或不去的最大值
           }
        }
    }
    
    int main()
    {
        int i,j,l,k,root;
        while(~scanf("%d",&t))
        {
            for(i = 1;i<=t;i++)
            scanf("%d",&dp[i][1]);
            root = 0;
            while(scanf("%d%d",&l,&k),l+k>0)
            {
                father[l] = k;//记录上司
                root = k;
            }
            memset(vis,0,sizeof(vis));
            dfs(root);
            printf("%d
    ",max(dp[root][1],dp[root][0]));
        }
    
        return 0;
    }
    
  • 相关阅读:
    Linux下安装Blender
    自我复制的3D打印机
    ODOO v10.0 自动生成财务凭证的科目设置
    初识Odoo的辅助核算
    Odoo9以后的社区版本和企业版功能上的区别
    06: linux中find查找命令总结
    02: shell中的if、case、for等语句
    01: shell基本使用
    05: 配置yum源
    04: linux基础总结-centos6.5
  • 原文地址:https://www.cnblogs.com/luckycode/p/5255644.html
Copyright © 2011-2022 走看看