【cf23E】Tree

本文介绍了如何使用树形动态规划解决一类树上的优化问题,即找到一种划分树的方法,使得每个子树大小乘积最大。通过状态设计f[i][j]表示以i为根的子树与i的父亲相连的节点数为j时的最大乘积,并给出转移方程。文章还提及了在实现过程中需要注意的高精度计算问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • link to problem
  • 【题目大意】
    给出一棵树,求一个对树的划分方法使得每棵子树大小的乘积最大。

  • 【题解】树上背包dp
    一看到题目的时候想的是贪心(?是可以的然而我太菜了不会?),因为曾经有一道题是拆分序列为2和3的什么什么的。。。= =扯远了
    {状态设计} f[i][j] 表示以 i 为根的子树中与 i 的父亲相连的有 j 个节点时,这棵子树的乘积最大值,故最终答案ans=f[1][0];
    {转移方程} f[i][j+k]=max(f[i][j]*f[son[i]][k]),其中 j<=size[i], k<=size[son[i]];

  • 【呆马初级版(⊙_⊙)】
#include <cstdio>
#include <cstring>
struct edge{ int to,nxt;}e[2000];
int n,cnt,s[1000],fi[1000],ans,f[705][705];
    void add(int u,int v)
    {
   
   
        e[++cnt].to=v;e[cnt].nxt=fi[u];fi[u]=cnt;
    }
    void dp(int x,int fa)
    {
   
   
        s[x]=1;f[x][1]=1;
        for (int i=fi[x];i;i=e[i].nxt)
            if (e[i].to!=fa)
            {
   
   
                dp(e[i].to,x);
                for (int j=s[x];j>=0;--j)
                    for (int k=s[e[i].to];k>=0;--k)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值