Neko and tree HDU - 6540 (树形dp)

这篇博客探讨了如何使用树形动态规划解决一个关于树的数学问题。给定一棵树和一些重要的节点,任务是找到满足最远两点距离不超过k的点集的不同选择方式。博主分享了思考过程和解决方案,指出在转移过程中需要维护前缀和以优化至线性时间复杂度,并解释了在计算总方案数时处理根节点的特殊情况。
摘要由CSDN通过智能技术生成

题意:给你一棵树,树上有一些重要的点,让你选一个只包含重要的点的点集,满足点集里最远的两个点不超过k,问有多少种选法

想了好久,题解说得太简略了。。。

dp[i][j]表示在i这颗子树中距离i点最远点距离为j的方案数。

考虑如何从子树转移,显然 我们遍历到一颗新子树时,要用之前的所有方案乘以这颗子树的方案来更新。

即dp[u][max(i,j+1) ]+=dp[u][i]*dp[to][j]

暴力更新的复杂度是k^2的。需要用前缀和维护一下,

最后如果这个点可选,那么有选这个点和不选这个点两种情况,要乘2,然后加上只有这个点的情况。

最后计算总和的时候,如果这个点不是根,只加上长度为k的情况,因为其他情况还有可能去更新,会在他的祖宗里计算到,如果不是加上所有方案。

#include <bits/stdc++.h>

using namespace std;
#define N 5010
#define ll long long
#define mod 1000000007
#define go(i,a,b) for(int i=(a);i<=(b);i++)
#define dep(i,a,b) for(int i=(a);i>=(b);i--)
#define add(a,b) ((a+=(b))%=mod)
ll dp[N][N],sum[N][N],f[N],ans;
vector<int>path[N];
int is[N];
int n,m,k,x,y;
void cal(int u,int to){
    go(i,1,k-1)f[i]=dp[u][i]*sum[to][min(i,k-i)-1]%mod;
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值