zoukankan      html  css  js  c++  java
  • hihocoder1055 刷油漆(树形DP)

    问题描述:

    有一棵树,树上节点编号1~n,其中节点1为根节点,树上的每个节点有其对应的一个价值。现在要减掉一些枝桠,只留下m个节点的一棵树(必须包含根节点),为这m个节点着色,约束条件是要使剩下m个节点的价值之和最大化。

    算法思路:

    状态定义:dp[x][j]表示以节点x为根的子树中,着色节点数目为j时,从这棵子树中所能获得的最大价值。那么dp[1][m]即为所求。

    状态转移:设节点y为节点x的子节点,那么dp[x][j] = max(dp[x][j], dp[y][k]+dp[x][j-k]),其中1<=k<j。

    整体思路类似于完全背包。

    我的代码:

     1 #include <iostream>
     2 #include <algorithm>
     3 #include <vector>
     4 #include <cstring>
     5 
     6 using namespace std;
     7 
     8 #define MAXN 105
     9 
    10 int dp[MAXN][MAXN], n, m, v[MAXN];
    11 bool vis[MAXN];
    12 struct Tree
    13 {
    14     vector<int> t[MAXN];
    15     void init(int n)
    16     {
    17         for(int i=1; i<=n; ++i) t[i].clear();
    18         memset(&vis[1], 0, n);
    19     }
    20     void addEdge(int a, int b)
    21     {
    22         t[a].push_back(b);
    23         t[b].push_back(a);
    24     }
    25     void solute(int x)
    26     {
    27         vis[x] = true;
    28         memset(dp[x], 0, (m+1)*sizeof(int));
    29         dp[x][1] = v[x];
    30         for(int i=0; i<t[x].size(); ++i)
    31         {
    32             int y = t[x][i];
    33             if(!vis[y])
    34             {
    35                 solute(y);
    36                 for(int j=m; j>=2; --j) //注意这里的遍历顺序
    37                 for(int k=1; k<j; ++k) dp[x][j] = max(dp[x][j], dp[x][j-k]+dp[y][k]);
    38             }
    39         }
    40     }
    41 }tree;
    42 
    43 int main()
    44 {
    45     while(cin>>n>>m)
    46     {
    47         for(int i=1; i<=n; ++i) cin>>v[i];
    48         tree.init(n);
    49         for(int i=0; i<n-1; ++i)
    50         {
    51             int a, b;
    52             cin>>a>>b;
    53             tree.addEdge(a, b);
    54         }
    55         tree.solute(1);
    56         cout<<dp[1][m]<<endl;
    57     }
    58 
    59     return 0;
    60 }

    题目来源:http://hihocoder.com/problemset/problem/1055

  • 相关阅读:
    CentOS7搭建elasticsearch集群
    Centos7搭建redis集群及安装sentinel
    编译安装haproxy开启支持SSL
    CentOS7单节点部署redis主从复制和sentinel
    CentOS7单节点部署redis-cluster
    搭建hadoop集群
    配置nginx为FastDFS的storage server提供http访问接口
    FastDFS分布式存储
    一键部署Kubernetes高可用集群
    一键部署ETCD集群脚本
  • 原文地址:https://www.cnblogs.com/pczhou/p/4296564.html
Copyright © 2011-2022 走看看