zoukankan      html  css  js  c++  java
  • HDU1561 The more, The Better(树形DP)

    题目是有n个存有宝藏的城堡,攻克任何一个城堡都需要先攻克0个或其他1个城堡,问攻克m个城堡最多能得到多少宝藏。

    题目给的城堡形成一个森林,添加一个超级根把森林连在一起就是树了,那么就考虑用树型DP:

    • dp[u][m]表示以u结点为根的子树攻克m个结点的最大价值

    但是这样转移太难了,根是从每个孩子通过各自分配若干的城堡去攻克转移的,一个排列组合数,阶乘,是指数级的时间复杂度!

    看了题解,原来这是依赖背包,没看背包九讲。。不过网上的博客似乎没说清楚,事实上这个状态应该是三个维度来表示:

    • dp[u][m][n]表示以u结点为根的子树,且只考虑u结点的前n个孩子,去攻克m个结点,所能得到的最大价值
    • 转移就是dp[u][m][n]=max(dp[u][m-k][n-1]+dp[u的第n个孩子][k][u的孩子个数])(0<=k<m)

    可以发现n只从n-1转移而来,那么就可以像01背包重复利用内存,这三维数组只用二维数组来实现,即:

    • dp[u][m]=max(dp[u][m-k]+dp[u’][k])(father[u']=u,0<=k<m)
    • m要从大到小枚举。

    代码感觉还不好实现。。感觉这题挺难的= =虽然听说这是树型DP入门题。。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 using namespace std;
     5 struct Edge{
     6     int u,v,next;
     7 }edge[222];
     8 int NE,head[222];
     9 void addEdge(int u,int v){
    10     edge[NE].u=u; edge[NE].v=v; edge[NE].next=head[u];
    11     head[u]=NE++;
    12 }
    13 int val[222],d[222][222];
    14 void dp(int u,int m){
    15     d[u][1]=val[u];
    16     for(int i=head[u]; i!=-1; i=edge[i].next){
    17         int v=edge[i].v;
    18         dp(v,m);
    19         for(int j=m; j>=2; --j){
    20             for(int k=0; k<j; ++k){
    21                 d[u][j]=max(d[u][j],d[u][j-k]+d[v][k]);
    22             }
    23         }
    24     }
    25 }
    26 int main(){
    27     int n,m,a;
    28     while(~scanf("%d%d",&n,&m) && (n||m)){
    29         NE=0;
    30         memset(head,-1,sizeof(head));
    31         for(int i=1; i<=n; ++i){
    32             scanf("%d%d",&a,val+i);
    33             addEdge(a,i);
    34         }
    35         memset(d,0,sizeof(d));
    36         dp(0,m+1);
    37         printf("%d
    ",d[0][m+1]);
    38     }
    39     return 0;
    40 }
  • 相关阅读:
    2019计蒜之道初赛第三场题解
    牛客小白月赛14 :部分题目总结
    CF-558:部分题目总结
    浙江省第十六届大学生ACM程序设计竞赛部分题解
    浙江省高职院校联合训练(一)
    CF-544:部分题目总结
    CF-552E-Two Teams
    CF-551:部分题目总结
    freemarker使用map替换字符串中的值
    freemarker使用map替换ftl中相关值
  • 原文地址:https://www.cnblogs.com/WABoss/p/5187207.html
Copyright © 2011-2022 走看看