UVALive 4685 Succession 树DP+背包
一、前言
这道题同样来自于红书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)。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define veci vector<int>
#define stai stack<int> const long long MAXN=;
const long long INF=<<;
const long long MOD=1e9+; veci G[MAXN];
ll arr[MAXN],dp[MAXN][MAXN],summ[MAXN][MAXN];
ll n,SHARE,ans,maxx,r; void dfs(int now,int last)
{
int len=G[now].size();
dp[now][]=;
summ[now][]=arr[now];
summ[now][]=;
for(int i=;i<len;++i)
{
int tar=G[now][i];
if(tar==last)continue;
dfs(tar,now); //使用0-1背包进行状态转移
for(int j=SHARE;j;j--)
{
for(int k=;k+j<=SHARE;++k)
{
ll newSum=summ[now][j]+summ[tar][k]; if(summ[now][j+k]==newSum)
{
dp[now][j+k]+=(dp[now][j]*dp[tar][k])%MOD;
dp[now][j+k]%=MOD;
}
if(summ[now][j+k]<newSum)
{
summ[now][j+k]=newSum;
dp[now][j+k]=(dp[now][j]*dp[tar][k])%MOD;
}
}
} }
if(maxx<summ[now][SHARE])
{
maxx=summ[now][SHARE];
ans=dp[now][SHARE];
}else if(maxx==summ[now][SHARE])
{
ans+=dp[now][SHARE];
ans%=MOD;
}
} void init()
{
cin>>n>>SHARE>>r;
ans=;maxx=-INF;
r=n-;
for(int i=;i<n;++i)
{
G[i].clear();
cin>>arr[i];
for(int j=;j<=SHARE;++j)
{
dp[i][j]=;
summ[i][j]=-INF;
}
}
while(r--)
{
int a,b;
cin>>a>>b;
G[a].push_back(b);
G[b].push_back(a);
}dfs(,-);
cout<<maxx<<" "<<ans<<"\n";
} int main()
{
cin.sync_with_stdio(false);
int ca;cin>>ca;
while(ca--)init(); return ;
}
UVALive 4685 Succession 树DP+背包的更多相关文章
- POJ 1947 Rebuilding Roads (树dp + 背包思想)
题目链接:http://poj.org/problem?id=1947 一共有n个节点,要求减去最少的边,行号剩下p个节点.问你去掉的最少边数. dp[u][j]表示u为子树根,且得到j个节点最少减去 ...
- UVALive 3942 字典树+dp
其实主要是想学一下字典树的写法,但这个题目又涉及到了DP:这个题目要求某些单词组成一个长子串的各种组合总数,数据量大,单纯枚举复杂度高,首先肯定是要把各个单词给建成字典树,但是之后该怎么推一时没想到. ...
- UVALive 3942 Remember the Word 字典树+dp
/** 题目:UVALive 3942 Remember the Word 链接:https://vjudge.net/problem/UVALive-3942 题意:给定一个字符串(长度最多3e5) ...
- POJ 3345-Bribing FIPA(树状背包)
题意: 有n个国家投票,要得到一个国家的投票有一定的花费,如果给到一个国家的票同时也得到了它所有附属国的票,给出国家关系树,求至少得到m票的最小花费. 分析:基础树状背包,dp[i][j],以i为根的 ...
- HDU 1561:The more, The Better(有依赖的树型背包)
http://acm.hdu.edu.cn/showproblem.php?pid=1561 题意:有n个点,容量为m,每个点有一个价值,还给出n条边,代表选第i个点之前必须先选ai,问最多的价值能取 ...
- URAL_1018 Binary Apple Tree 树形DP+背包
这个题目给定一棵树,以及树的每个树枝的苹果数量,要求在保留K个树枝的情况下最多能保留多少个苹果 一看就觉得是个树形DP,然后想出 dp[i][j]来表示第i个节点保留j个树枝的最大苹果数,但是在树形过 ...
- 【题解】LOJ2462完美的集合(树DP 魔改Lucas)
[题解]LOJ2462完美的集合(树DP 魔改Lucas) 省选模拟考这个??????????????????? 题目大意: 有一棵树,每个点有两个属性,一个是重量\(w_i\)一个是价值\(v_i\ ...
- 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 ...
- HDU4916 Count on the path(树dp??)
这道题的题意其实有点略晦涩,定义f(a,b)为 minimum of vertices not on the path between vertices a and b. 其实它加一个minimum ...
随机推荐
- postgresql安装,java简单使用postgresql
一 整合 由于本人的学过的技术太多太乱了,于是决定一个一个的整合到一个springboot项目里面. 附上自己的github项目地址 https://github.com/247292980/spri ...
- Ionic 解决gradle下载慢的问题
问题 使用Ioinc添加安卓平台或者编译的时候,提示gradle-XXX-all.zip下载,此进度缓慢. 解决 下载gradle对应的zip文件. 参考资源:http://services.grad ...
- Vue小贴士
1.去掉空格影响,删除掉此段代码 2.想要同时运行两个Vue项目,修改端口号,黄色框内的内容自己随意改个端口号就行,比如:8082 3.批处理 在项目的根目录中添加a.bat文件,这样就可以在运行的 ...
- Java中的while循环——通过示例学习Java编程(10)
作者:CHAITANYA SINGH 来源:https://www.koofun.com/pro/kfpostsdetail?kfpostsid=20 在上一个教程中,我们讨论了for循环的用法.在本 ...
- java8Stream map和flatmap的区别
map和flatmap的区别 map只是一维 1对1 的映射 而flatmap可以将一个2维的集合映射成一个一维,相当于他映射的深度比map深了一层 , 所以名称上就把map加了个flat 叫flat ...
- 1 误删dbf文件造成ORA-01109: 数据库未打开.
1.cmd-sqlplus /nolog-conn system/pwd as sysdba 2.shutdown immediate; 3.startup mount; 4.alter databa ...
- 【干货】JavaScript DOM编程艺术学习笔记7-9
七.动态创建标记 在文档中不写占位图片和文字代码,在能调用js的情况下动态创建,文档支持性更好. 在原来的addLoadEvent prepareGallery showPic的基础上增加函数prep ...
- Java栈,PC寄存器,本地方法栈,堆,方法区(静态区)和运行常量池
详情参考:https://my.oschina.net/wangsifangyuan/blog/711329 前言:当要判断一个变量存在什么空间上哪儿时,先分析它是哪一种(是实例变量还是局部变量),实 ...
- linux 命令——53 route(转)
Linux系统的route 命令用于显示和操作IP路由表(show / manipulate the IP routing table).要实现两个不同的子网之间的通信,需 要一台连接两个网络的路由器 ...
- Hystrix + Hystrix Dashboard搭建(Spring Cloud 2.X)
本机IP为 192.168.1.102 一.搭建Hystrix Dashboard 1. 新建 Maven 项目 hystrix-dashboard 2. pom.xml <projec ...