热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

51Nod1353树

51Nod1353树传送门思路我们定义\(dp[i][j]\)代表第i个点联通块大小为j的方案总数,也可以把它理解为等待分配(不确定归属)的联通块大小为j的方案总数。那么每次转移我

51Nod1353 树

传送门


思路

我们定义\(dp[i][j]\)代表第i个点联通块大小为j的方案总数,也可以把它理解为等待分配(不确定归属)的联通块大小为j的方案总数。

那么每次转移我们就使用一个类似背包的东西来统计答案。

对于一个节点的每个儿子,我们只需要从大到小遍历所有可用的j_nowj_now上限就是所有遍历过的点子树大小的和)。然后再枚举这个儿子的j_son,那么显然我们就获得了很多第i个点联通块大小为j_son+j_now的方案。dp[i][j_son+j_now]+=dp[i][j_now]*dp[son][j_son]累计一下答案即可。需要注意的是,j_now需要从大往小遍历,因为反过来的话方案会算重(自己想一下01背包和完全背包)。另外,j_son是可以为0的,dp[son][0]代表son这个点只会包含在son子树内的联通块。所以对于每一个j_now都需要dp[now][j_now]*=dp[son][0]

在状态转移完后,对于每一个\(j\geq k\)我们都要执行操作dp[now][0]+=dp[now][j]。相当于分了一块大小为j的联通块。想一想就知道为什么了。

其实就是道树形依赖背包的模版。


代码

#include
#include
#include
#include
#include
#define ll long long
#define maxn 2050
#define mod (int)(1e9+7)
using namespace std;
ll dp[maxn][maxn],ans;
int head[maxn],cnt,n,k,size[maxn];
struct gg {
int u,v,next;
}side[maxn*2];
void insert(int u,int v) {
struct gg add={u,v,head[u]};side[++cnt]=add;head[u]=cnt;
}
void dfs(int now,int fa) {
size[now]=1;
dp[now][1]=1;
for(int i=head[now];i;i=side[i].next) {
int v=side[i].v;if(v==fa)continue;
dfs(v,now);
for(int j1=size[now];j1>=1;j1--) {
for(int j2=1;j2<=size[v];j2++) {
dp[now][j1+j2]+=(dp[now][j1]*dp[v][j2])%mod;dp[now][j1+j2]%=mod;
}
dp[now][j1]*=dp[v][0];dp[now][j1]%=mod;
}
size[now]+=size[v];
}
for(int i=k;i<=size[now];i++)dp[now][0]+=dp[now][i],dp[now][0]%=mod;
}
int main() {
scanf("%d%d",&n,&k);
for(int i=1;i int a,b;scanf("%d%d",&a,&b);insert(a,b);insert(b,a);
}
dfs(1,0);
for(int i=k;i<=n;i++)ans+=dp[1][i],ans%=mod;
printf("%lld",ans);
return 0;
}



推荐阅读
  • 本文深入探讨 MyBatis 中动态 SQL 的使用方法,包括 if/where、trim 自定义字符串截取规则、choose 分支选择、封装查询和修改条件的 where/set 标签、批量处理的 foreach 标签以及内置参数和 bind 的用法。 ... [详细]
  • 扫描线三巨头 hdu1928hdu 1255  hdu 1542 [POJ 1151]
    学习链接:http:blog.csdn.netlwt36articledetails48908031学习扫描线主要学习的是一种扫描的思想,后期可以求解很 ... [详细]
  • 本实验主要探讨了二叉排序树(BST)的基本操作,包括创建、查找和删除节点。通过具体实例和代码实现,详细介绍了如何使用递归和非递归方法进行关键字查找,并展示了删除特定节点后的树结构变化。 ... [详细]
  • 本文详细介绍了C语言中链表的两种动态创建方法——头插法和尾插法,包括具体的实现代码和运行示例。通过这些内容,读者可以更好地理解和掌握链表的基本操作。 ... [详细]
  • 本文详细探讨了VxWorks操作系统中双向链表和环形缓冲区的实现原理及使用方法,通过具体示例代码加深理解。 ... [详细]
  • 本文探讨了如何通过最小生成树(MST)来计算严格次小生成树。在处理过程中,需特别注意所有边权重相等的情况,以避免错误。我们首先构建最小生成树,然后枚举每条非树边,检查其是否能形成更优的次小生成树。 ... [详细]
  • Windows服务与数据库交互问题解析
    本文探讨了在Windows 10(64位)环境下开发的Windows服务,旨在定期向本地MS SQL Server (v.11)插入记录。尽管服务已成功安装并运行,但记录并未正确插入。我们将详细分析可能的原因及解决方案。 ... [详细]
  • Explore how Matterverse is redefining the metaverse experience, creating immersive and meaningful virtual environments that foster genuine connections and economic opportunities. ... [详细]
  • ImmutableX Poised to Pioneer Web3 Gaming Revolution
    ImmutableX is set to spearhead the evolution of Web3 gaming, with its innovative technologies and strategic partnerships driving significant advancements in the industry. ... [详细]
  • 本教程涵盖OpenGL基础操作及直线光栅化技术,包括点的绘制、简单图形绘制、直线绘制以及DDA和中点画线算法。通过逐步实践,帮助读者掌握OpenGL的基本使用方法。 ... [详细]
  • 本题涉及一棵由N个节点组成的树(共有N-1条边),初始时所有节点均为白色。题目要求处理两种操作:一是改变某个节点的颜色(从白变黑或从黑变白);二是查询从根节点到指定节点路径上的第一个黑色节点,若无则输出-1。 ... [详细]
  • Linux设备驱动程序:异步时间操作与调度机制
    本文介绍了Linux内核中的几种异步延迟操作方法,包括内核定时器、tasklet机制和工作队列。这些机制允许在未来的某个时间点执行任务,而无需阻塞当前线程,从而提高系统的响应性和效率。 ... [详细]
  • 深入探讨CPU虚拟化与KVM内存管理
    本文详细介绍了现代服务器架构中的CPU虚拟化技术,包括SMP、NUMA和MPP三种多处理器结构,并深入探讨了KVM的内存虚拟化机制。通过对比不同架构的特点和应用场景,帮助读者理解如何选择最适合的架构以优化性能。 ... [详细]
  • Codeforces Round #566 (Div. 2) A~F个人题解
    Dashboard-CodeforcesRound#566(Div.2)-CodeforcesA.FillingShapes题意:给你一个的表格,你 ... [详细]
  • 本题通过将每个矩形视为一个节点,根据其相对位置构建拓扑图,并利用深度优先搜索(DFS)或状态压缩动态规划(DP)求解最小涂色次数。本文详细解析了该问题的建模思路与算法实现。 ... [详细]
author-avatar
乘浪追风2010_210
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有