一、前言

  这道题同样来自于红书P142,作为树DP专题中的一道比较难的题目,A了一天左右的时间,看上去事实证明,这题的难度理我本身的实力还是有些太远了,于是正确的做法应该是分析一下题目之后进行解析什么的之后上VJ找AC代码,然后结合对状态转移方程的理解补出题解中没有提到或者。。搞错了的部分。于是看上去只有这种方法能够比较高效的进行自我扫盲什么的。作为一只萌新,成功的在刷这本书的过程中体验到了所谓“菜是原罪”这种奇妙的含义。

二、题意

  原题很长,但是大概的意思是,N各节点的一棵树,要求你找出,K大小的联通块中的权值最大值,以及所有能够构成最大值的K大联通块的构成方案数。

三、思路和坑

  这道题作为卡了我好久的一道题,看上去思路和前面一篇苹果树的题目有些奇妙的异曲同工之处——都是一个套路甚至代码可以互相改了用

  大概的思路是设置两个状态转移方程进行同步转移:

 1、DP【】【】用来保存“某节点,权值最大的,大小为J的联通块的组成数量”

 2、SUMM【】【】用来保存某节点权值最大的,大小为J的联通块的权值

  于是,我们可以子啊转移SUMM【】【】的时候把DP【】【】作为一个附属属性进行转移:当相同的时候进行加和,但是当有最大值出现的时候直接复制最大值的解决方案。

对于如何进行枚举实际上很容易想到的是0-1背包:
对于每个大小的子节点视为物品:权重是ARR[TAR],重量是尺寸。
之后认为背包容量就是总容量:SHARE,也就是前文提到的k。然后使用0-1背包特有的从上到下的方式进行状态转移。每个DFS中看上去有三重循环但是实际上由于每个节点只会被调用一次所以实际上时间复杂度是O(N*SHARE)。

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define ll long long
  4. #define veci vector<int>
  5. #define stai stack<int>
  6.  
  7. const long long MAXN=;
  8. const long long INF=<<;
  9. const long long MOD=1e9+;
  10.  
  11. veci G[MAXN];
  12. ll arr[MAXN],dp[MAXN][MAXN],summ[MAXN][MAXN];
  13. ll n,SHARE,ans,maxx,r;
  14.  
  15. void dfs(int now,int last)
  16. {
  17. int len=G[now].size();
  18. dp[now][]=;
  19. summ[now][]=arr[now];
  20. summ[now][]=;
  21. for(int i=;i<len;++i)
  22. {
  23. int tar=G[now][i];
  24. if(tar==last)continue;
  25. dfs(tar,now);
  26.  
  27. //使用0-1背包进行状态转移
  28. for(int j=SHARE;j;j--)
  29. {
  30. for(int k=;k+j<=SHARE;++k)
  31. {
  32. ll newSum=summ[now][j]+summ[tar][k];
  33.  
  34. if(summ[now][j+k]==newSum)
  35. {
  36. dp[now][j+k]+=(dp[now][j]*dp[tar][k])%MOD;
  37. dp[now][j+k]%=MOD;
  38. }
  39. if(summ[now][j+k]<newSum)
  40. {
  41. summ[now][j+k]=newSum;
  42. dp[now][j+k]=(dp[now][j]*dp[tar][k])%MOD;
  43. }
  44. }
  45. }
  46.  
  47. }
  48. if(maxx<summ[now][SHARE])
  49. {
  50. maxx=summ[now][SHARE];
  51. ans=dp[now][SHARE];
  52. }else if(maxx==summ[now][SHARE])
  53. {
  54. ans+=dp[now][SHARE];
  55. ans%=MOD;
  56. }
  57. }
  58.  
  59. void init()
  60. {
  61. cin>>n>>SHARE>>r;
  62. ans=;maxx=-INF;
  63. r=n-;
  64. for(int i=;i<n;++i)
  65. {
  66. G[i].clear();
  67. cin>>arr[i];
  68. for(int j=;j<=SHARE;++j)
  69. {
  70. dp[i][j]=;
  71. summ[i][j]=-INF;
  72. }
  73. }
  74. while(r--)
  75. {
  76. int a,b;
  77. cin>>a>>b;
  78. G[a].push_back(b);
  79. G[b].push_back(a);
  80. }dfs(,-);
  81. cout<<maxx<<" "<<ans<<"\n";
  82. }
  83.  
  84. int main()
  85. {
  86. cin.sync_with_stdio(false);
  87. int ca;cin>>ca;
  88. while(ca--)init();
  89.  
  90. return ;
  91. }

UVALive 4685 Succession 树DP+背包的更多相关文章

  1. POJ 1947 Rebuilding Roads (树dp + 背包思想)

    题目链接:http://poj.org/problem?id=1947 一共有n个节点,要求减去最少的边,行号剩下p个节点.问你去掉的最少边数. dp[u][j]表示u为子树根,且得到j个节点最少减去 ...

  2. UVALive 3942 字典树+dp

    其实主要是想学一下字典树的写法,但这个题目又涉及到了DP:这个题目要求某些单词组成一个长子串的各种组合总数,数据量大,单纯枚举复杂度高,首先肯定是要把各个单词给建成字典树,但是之后该怎么推一时没想到. ...

  3. UVALive 3942 Remember the Word 字典树+dp

    /** 题目:UVALive 3942 Remember the Word 链接:https://vjudge.net/problem/UVALive-3942 题意:给定一个字符串(长度最多3e5) ...

  4. POJ 3345-Bribing FIPA(树状背包)

    题意: 有n个国家投票,要得到一个国家的投票有一定的花费,如果给到一个国家的票同时也得到了它所有附属国的票,给出国家关系树,求至少得到m票的最小花费. 分析:基础树状背包,dp[i][j],以i为根的 ...

  5. HDU 1561:The more, The Better(有依赖的树型背包)

    http://acm.hdu.edu.cn/showproblem.php?pid=1561 题意:有n个点,容量为m,每个点有一个价值,还给出n条边,代表选第i个点之前必须先选ai,问最多的价值能取 ...

  6. URAL_1018 Binary Apple Tree 树形DP+背包

    这个题目给定一棵树,以及树的每个树枝的苹果数量,要求在保留K个树枝的情况下最多能保留多少个苹果 一看就觉得是个树形DP,然后想出 dp[i][j]来表示第i个节点保留j个树枝的最大苹果数,但是在树形过 ...

  7. 【题解】LOJ2462完美的集合(树DP 魔改Lucas)

    [题解]LOJ2462完美的集合(树DP 魔改Lucas) 省选模拟考这个??????????????????? 题目大意: 有一棵树,每个点有两个属性,一个是重量\(w_i\)一个是价值\(v_i\ ...

  8. CF456D A Lot of Games (字典树+DP)

    D - A Lot of Games CF#260 Div2 D题 CF#260 Div1 B题 Codeforces Round #260 CF455B D. A Lot of Games time ...

  9. HDU4916 Count on the path(树dp??)

    这道题的题意其实有点略晦涩,定义f(a,b)为 minimum of vertices not on the path between vertices a and b. 其实它加一个minimum ...

随机推荐

  1. 从零开始的全栈工程师——js篇2.14(表单与计时器)

    一.表单 Form input select textarea type=”radio/checkbox/password/button/text/submit/reset/” 表单的事件 oncha ...

  2. h5 本地存储

    H5本地存储有两个API,一个是Web Storage,还有一个是Web SQL.不管是哪一个,都是基于JavaScript语言来使用,接下来我就教你怎么使用H5本地存储,本文篇幅较大,JS代码较多, ...

  3. Spring Boot相关组件的添加

    在勾选相关组件后, pom.xml文件上发生了根本的变化 1.这是最简单的项目的pom文件 <?xml version="1.0" encoding="UTF-8& ...

  4. 几幅手稿讲解CNN

    学习深度神经网络方面的算法已经有一段时间了,对目前比较经典的模型也有了一些了解.这种曾经一度低迷的方法现在已经吸引了很多领域的目光,在几年前仅仅存在于研究者想象中的应用,近几年也相继被深度学习方法实现 ...

  5. GBase数据库存储过程——批量删除多个数据表的数据

    偶尔需要清空一下数据库,重装成本太高. --清空历史存储过程 DROP Procedure `dap_model`.`delete_datas` ; --创建存储过程 DELIMITER // CRE ...

  6. hihoCoder #1044 : 状态压缩·一 (清垃圾)

    题意: 某车厢有一列座位,共有n个位置,清洁工要在这n个位置上清垃圾,但是不能全部位置都清理,只能选择部分.选择的规则是,连续的m个位置内,不能够清理超过q个,也就是说从第1~m个位置最多可以清q个, ...

  7. Hybris Enterprise Commerce Platform 服务层的设计与实现

    Hybris Enterprise Commerce Platform这个系列之前已经由我的同事,SAP成都研究院Hybris开发团队的同事张健(Zhang Jonathan)发布过两篇文章了.这里J ...

  8. IOS 进程描述

    ● 什么是进程 ● 进程是指在系统中正在运行的一个应用程序 ● 每个进程之间是独立的,每个进程均运行在其专用且受保护的内存空间内 ● 通过“活动监视器”可以查看Mac系统中所开启的进程

  9. 基于GMap.NET地图下载器的开发和研究

    基于GMap.NET地图下载器的开发和研究 软件下载地址:https://pan.baidu.com/s/1ay0aOm3fiZ35vlfD8kFYFw 1.地图浏览功能 可以浏览谷歌地图.百度.ar ...

  10. 关于小程序 input 组件内容显示不全(显示的长度不满 input 宽度)问题

    问题:小程序的input组件经常用到,但在使用input组件的时候会出现一种现象:明明设置了input的宽度,但是输入的内容显示的长度范围却怎么都不到一整个input组件的宽度,而且后面没显示的地方无 ...