[树上依赖多重背包 DP] BZOJ 4910 [Sdoi2017]苹果树

树上背包问题 树上背包问题树上背包问题算法原理例题一:有依赖的背包问题题意数据范围思路代码例题二:二叉苹果树题意数据范围思路代码例题三:Factories(2018icpc宁夏网络赛)题意数据范围思路代码 树上背包问题 一些题目给定了树形结构,在这个树形结构中选取一定数量的点或边(也可能是其他属性),使得某种与点权或者边权相关的花费最大或者最小。解决这类问题,一般要考虑使用树上背包。 算法原理 树上背包,顾名思义,就是在树上做背包问题。一个节点的若干子树可以看作是若干组背包,也就是用树形dp的方式做分组背包问题。一般来说 阅读详情

题目 t−h≤k 的限制其实就是选一条到叶节点的链,然后再选k个的最大值(因为vi都大于零)。

因为 ai>1 的点,肯定是先选了第一个才会选第二个
所以可以把 ai>1 的点拆成两个点 i′,i′′,ai′=1,ai′′=ai−1,让 i′′ 变成 i′ 的儿子。

这个树上依赖背包可以通过两个遍历子树顺序相反的后序遍历和队列优化 O(NK) 求出每个点选 K 个的最大价值。

然后枚举每个叶子(拆点前的叶子),用两个后序遍历中的DP值更新答案就可以了。

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>

using namespace std;

typedef long long ll;

const int N=40010,K=500010;


bool bg;
int t,n,k,cnt,ncnt,DEPT,iG[N],a[N],v[N],lef[N],dpt[N],sz[N],son[N];
int f[51000010],g[51000010];
int val[N];
ll tot;
struct edge{
  int t,nx;
}E[N];

int Ap[N],Bp[N],pa[N],pb[N],A[N],B[N],At,Bt;

inline char nc(){
  static char buf[100000],*p1=buf,*p2=buf;
  return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}

inline void rea(int &x){
  char c=nc(); x=0;
  for(;c>'9'||c<'0';c=nc());for(;c>='0'&&c<='9';x=x*10+c-'0',c=nc());
}

inline void adde(int x,int y){
  E[++cnt].t=y; E[cnt].nx=iG[x]; iG[x]=cnt;
}

void dfsf(int x){
  Ap[x]=At; sz[x]=1;
  for(int i=iG[x];i;i=E[i].nx){
    val[E[i].t]=val[x]+v[E[i].t];
    dpt[E[i].t]=dpt[x]+1;
    dfsf(E[i].t),sz[x]+=sz[E[i].t];
  }
  A[++At]=x; pa[x]=At;
}

void dfsb(int x){
  vector<int> son; Bp[x]=Bt;
  for(int i=iG[x];i;i=E[i].nx)    son.push_back(E[i].t);
  for(int i=son.size()-1;~i;i--) dfsb(son[i]);
  B[++Bt]=x; pb[x]=Bt;
}

#define F(x,y) f[(x)*(k+1)+(y)]
#define G(x,y) g[(x)*(k+1)+(y)]

//ll &F(int x,int y){ return f[(x)*(k+1)+(y)]; }
//ll &G(int x,int y){ return g[(x)*(k+1)+(y)]; }

int Q[K],Q1[K],qh,qt;

bool ed;

inline void DP(int *A,int *p,int *f){
  for(int i=1;i<=ncnt;i++){
    int x=A[i];
    int *ff=f+(i-1)*(k+1),*fc=f+i*(k+1);
    memcpy(fc,f+p[x]*(k+1),sizeof(int)*(k+1));
    //for(int j=0;j<=k;j++) fc[j]=F(p[x],j);
    if(a[x]==0) continue;
    if(a[x]==1){
      for(int j=1;j<=k;j++)
        fc[j]=max(fc[j],ff[j-1]+v[x]);
      continue;
    }
    qh=qt=1;
    Q[qh]=0; Q1[qh]=0;
    for(int j=1;j<=k;j++){
      fc[j]=max(fc[j],j*v[x]+Q1[qh]);
      while(qh<=qt && Q[qh]<=j-a[x]) qh++;
      int cur=ff[j]-j*v[x];
      while(qh<=qt && Q1[qt]<cur) qt--;
      Q[++qt]=j; Q1[qt]=cur;
    }
  }
}

int ans;

int main(){
  rea(t);
  while(t--){
    rea(n); rea(k);
    for(int i=1;i<=n;i++) iG[i]=lef[i]=val[i]=son[i]=0;
    //memset(f,0,sizeof(f));
    //memset(g,0,sizeof(g));
    cnt=0; ncnt=n; At=Bt=0; ans=0; tot=0;
    for(int i=1;i<=n;i++){
      int p; rea(p); rea(a[i]); rea(v[i]); tot+=a[i];
      if(p) adde(p,i),lef[p]=1;
      if(a[i]>1)
        a[son[i]=++ncnt]=a[i]-1,v[ncnt]=v[i],a[i]=1,adde(i,ncnt),lef[ncnt]=1;
    }
    val[1]=v[1]; dpt[1]=1;
    dfsf(1); dfsb(1);
    DP(A,Ap,f);
    DP(B,Bp,g);
    //printf("%d\n",clock()-ttt);
    /*for(int i=1;i<=n;i++)
        for(int j=0;j<=k;j++)
            cout<<i<<' '<<j<<' '<<F(pa[i],j)<<' '<<G(pb[i],j)<<endl;*/
    for(int i=1;i<=n;i++)
      if(!lef[i]){
        int cur=min((ll)k,tot-dpt[i]);
        int *ff=f+(pa[i]-1)*(k+1),*gg=g+(pb[i]-sz[i])*(k+1);
        for(int j=0;j<=cur;j++)
          ans=max(ans,ff[j]+gg[cur-j]+val[i]);
      }
    //printf("%d\n",clock()-ttt);
    printf("%d\n",ans);
  }
  //printf("%d\n",(&ed-&bg)/1024/1024);
    return 0;
}
深入RK3588嵌入式Linux开发:uboot源码定制化移植实战 本文详细介绍了RK3588嵌入式Linux开发中,如何绕过庞大的官方SDK,从官方仓库获取纯净U-Boot源码并进行定制化移植的完整实战流程。内容包括编译环境搭建、交叉工具链配置、源码结构解析、设备树(Device Tree)修改、环境变量定制、编译脚本编写以及常见问题调试技巧,旨在帮助开发者深入理解系统引导过程,掌握为定制硬件适配U-Boot的核心技能。 阅读详情

相关推荐

【技能---ubuntu20.04更换国内镜像源】

安装好ubuntu20.04后,在下载软件等安装包的时候,速度特别的慢,为此就想着更换一下镜像源,以此来增加下载的速度!!!下面是换源的具体流程!!!提示:以下是本篇文章正文内容,下面案例可供参考以上到这里就更换完软件源了,如有不足之处,请大家斧正!!!

fyc300的博客 1万+

背包九讲——树形背包问题(有依赖的背包)

树形背包也叫有依赖的背包,是一种背包问题的变体,与传统的背包问题不同的是,物品之间存在一定的层次结构,形成了一棵树。每个节点代表一个物品,节点之间通过边连接,表示层次关系。问题的目标是在遍历这棵树的过程中,选择一些物品放入背包,使得背包中物品的总价值最大。 在树形背包问题中,一个节点可以选择放入背包,也可以选择不放入背包。如果选择放入,就需要考虑该节点的子节点;如果选择不放入,可以考虑其他兄弟节点。问题的关键是如何在遍历树的过程中,动态规划地计算每个节点的状态。

闻道有先后,术业有专攻 4277

【ros】ROS1的安装和相关使用方法

主要学习ros相关内容

Greary的博客 2379

树形DP&树形背包——深入理解

树形DP。

R的博客 2128

基于轻量级神经网络MobileNet V2的水果识别种类算法研究

本文阐述了一种基于轻量级卷积神经网络MobileNet V2的水果分类与识别算法研究。为了最大限度地促进机械收获,需要一个检测系统,它可以让我们识别不同类别的水果。一个相对未开发的想法是使用深度学习和人工智能算法,不仅可以检测水果的种类,还可以检测水果是否成熟。这可以证明是有利可图的,因为它可以提供作物生长状况以及成熟和未成熟果实的个体数量,以及决定是否是收获时间的有用信息。第一步对数据进行了预处理,数据预处理技术在众多的深度学习计算中起到了重要作用。

qq_43556680的博客 1640

给宇树Go2机器人装‘眼睛’:在Jetson Orin Nano上从零部署YOLOv5的保姆级避坑实录

本文详细介绍了在Jetson Orin Nano上为宇树Go2机器人部署YOLOv5视觉系统的完整流程,涵盖硬件选型、环境配置、模型优化及系统集成等关键步骤。针对机器人应用场景特有的离线部署、版本冲突和实时推理等挑战,提供了实用的解决方案和性能优化技巧,帮助开发者快速实现机器人的视觉能力升级。

weixin_29169505的博客 378

【动态规划】树上背包,依赖背包的小技巧

前排提醒,本文转载自 Sshwy's Notes 转载仅供学习使用。 可能大家都知道树上背包合并 \(O(n^3)\) 对子树大小取min可以优化到 \(O(n^2)\) 。但是对于树上依赖背包问题,背包合并的复杂度仍不能接受。考虑形式化的问题: 一棵 \(n\)​ 个结点有根树,每个结点 \(i\)​ 有 \(s_i\)​ 个价格为 \(c_i\) ,价值为 \(v_i\) 的物品。除了...

橘嘉禾 358

如何制作DOS启动盘 U盘制作DOS启动盘 HP-U盘启动DOS7 详细步骤教程 Intel网卡使用软件 bootutil lanconfig eeupdate Intel网卡修改MAC地址教程

制作DOS启动盘不是一项复杂的任务,只要按照以下简单的步骤进行操作,您就可以自己动手制作一个DOS启动盘。

lcy524514826的博客 896

BZOJ.4910.[SDOI2017]苹果树(树形依赖背包 DP 单调队列)

BZOJ 洛谷 \(shadowice\)已经把他的思路说的很清楚了,可以先看一下会更好理解? 这篇主要是对\(Claris\)题解的简单说明。与\(shadowice\)的做法还是有差异的(比如并没有明显用到后序遍历的性质),而且用这种写法可能跑的比较轻松? (另外你只要想明白\(f,h\)是代表啥,就很好理解了...) 问题等价于树形依赖背包,允许一条链每个点各免费取一次。 免费...

weixin_30687587的博客 141

2026年ERP选型实战:按规模分档,避开成本与实施陷阱

企业资源计划(ERP)是现代企业数字化转型的核心系统,它将财务、供应链、制造、人力等业务整合到统一平台。随着云计算和人工智能技术的发展,ERP已从传统本地部署的记录工具演变为SaaS订阅制、具备AI辅助决策能力的智能运营平台。不同规模企业在选型时的关注点差异巨大:小微企业追求轻量化和快速出报表,中型企业需要在流程标准化与业务灵活性间取得平衡,大型集团则注重多法人管控和数据治理。此外,制造、电商、工程等行业对ERP的模块要求也各有侧重,成本核算数据跑不通更是普遍痛点。如何结合企业规模与行业特征,制定合理的选型

weixin_34320724的博客 378

2025年最新雷电模拟器9.22安装Magisk面具和LSPosed框架完整图文教程 文章末尾附所需软件下载

操作环境:雷电模拟器9.0.22 虚拟系统版本android 91、设置-其他设置-Root权限-开启2、设置-性能设置-System.vmdk可写入3、安装Magisk-18a0b94a-delta(25205).apk,运行并给予root权限4、选择右上角安装弹出“允许“magisk Delta”访问您设备上的照片、媒体内容和文件吗?“选择允许,然后结束magisk进程。5、从新运行magisk选择右上角安装-选择修补boot镜像中的vbmeta和安装到Recovery。

代码简单说 Vue、JAVA、PHP、Node.js 熟练运用,接口、架构、性能全搞定。 7094

树上背包学习笔记

树上背包,顾名思义,就是在树上跑背包。Q:那么到底为什么要树上跑呢?A:因为我们到现在学的背包 dp 还是属于较浅的一类,什么 01 背包、完全背包还是多重背包,不如先看一个引入题。

weixin_42366947的博客 1562

【语音识别】基于MFCC特征实现说话人语音识别matlab源码

1 模型 采用能够反映人对语音的感知特性的Mel频率倒谱系数(MFCC)作为特征参数,以及为避免时间规整问题采用矢量量化技术开发的说话人识别系统.MFCC主要的是模拟人耳的听觉过程,相对于其它参数它对语音波形的变化不敏感,更加稳定,系统取得很好的识别结果,实验表明系统训练和识别的计算量和存储量都比较低. 2 部分代码 functionvarargout=Main(varargin) % MAIN M-file for Main.fig % MAIN, by itself...

qq_59747472的博客 848

树形DP学习笔记

树形 DP,即在树上进行的 DP。由于树固有的递归性质,树形 DP 一般都是递归进行的。对于每个节点 X,先递归在它的每个子节点上进行 DP,在回溯时,从子节点向节点 X 进行状态转移。

weixin_46390472的博客 625

org.apache.poi.xwpf.converter.pdf-1.0.6.zip

org.apache.poi.xwpf.converter.pdf-1.0.6org.apache.poi.xwpf.converter.core-1.0.6org.apache.poi.xwpf.converter-0.9.1

省-空气流通系数数据集.xlsx

详细介绍及样例数据:https://blog.youkuaiyun.com/T0620514/article/details/149606452

ZOJ 3201 Tree of Tree(树上背包)

题目链接: Tree of Tree   题意: 有一棵树,每个节点有一个权值,给定一个值k,求大小为k的子树中每个节点权值和最大为多少。   思路: 树规方程:f(i,j)=max{ f(i,j-p)+f(v,p) | 1&lt;p&lt;j 且 v是i的子节点 } f(i,j):表示以i为根节点,大小为 j 的子树的最大权值。 siz[i]:表示以 i 为根节点的子树大小。 ...

残阳止水 495

基于PyTorch的医学图像分割基础框架设计源码

本项目为基于PyTorch构建的医学图像分割基础框架设计源码,总计包含116个文件,涵盖75个PNG图像、17个Python源代码文件、12个Python编译文件、10个文本文件、1个Git忽略规则文件及1个Markdown文件。该框架专注于医学图像分割领域,旨在提供一套基础且实用的解决方案。

树上背包问题动态规划

树上背包问题动态规划

2201_75867204的博客 616

lyapunov.zip_Lyapunov指数_MATLAB lyapunov_duffing的lyapunov_最大Lyap

用于计算duffing 方程的最大lyapunov指数

树上背包

思路:dp[i][j]表示以i为根节点选出体积不超过j的最大价值。因为根节点必选所以我们吧dp[i][v[i]~m]全部置为w[i],对于每个节点如何选他的子节点就是在他所有的子节点中选一个,那么我们就可以吧他看成一个分组背包。体积的决策空间在j=m——v[i]之间因为小于v[i]根节点就不能选了,他的子节点就是在0——j-v[i]。 #include <cstdio> #include <cstring> #include <algorithm> #include...

Ray.C.L的博客 463

《树上(分组)背包》基础概念

本文介绍了树上分组背包问题算法,该算法结合树形结构和背包问题,解决具有依赖关系的资源优化问题。算法通过递归处理树节点,定义状态dp[i][j]表示子树i在容量j时的最优价值,采用自底向上方式计算。核心步骤包括初始化状态、递归处理子树、状态转移以及结果获取。伪代码展示了具体实现,包括数据结构定义、初始化函数、递归DFS和结果计算。时间复杂度主要取决于节点数和背包容量,最坏情况下为O(n×V²),空间复杂度为O(n×V)。该算法适用于公司资源分配等树形依赖场景。

英雄哪里出来 1220

【树形背包】学习笔记 | 例题

目录定义模板例题P2014[CTSC1997]选课P1273有线电视网P1272重建道路 定义 顾名思义,树形背包就是在树上进行背包的操作。据我的理解,树形背包就类似于在每一棵子树中找一些节点,可以取也可以不取,但必须满足依赖性(如果选择了子节点,父节点也一定要被选)。这样我们就可以在不同子树之间进行状态转移,其实也相当于分组背包(第一维枚举子树,第二维枚举容量,第三维枚举决策)。 基础的状态转移方程 dp[x][j] = max(dp[x][j], dp[x][j-k] +

kaka03200的博客 406

一种树形背包的复杂度证明

有一类树上背包(例如 CF1097G Vladislav and a Great Legend),第二维表示子树内选的点数且限制第二维不超过mmm,其总复杂度可证明为O(nm)O(nm)O(nm)。 它们的代码一般长这样: void dfs(int u,int last) { sz[u]=1; // initialize dp[u] for(int k=head[u];k;k=e[k].ne...

这个博客已经搬到了:zhongyuwei.github.io 2265

重刷树形背包计划!

一.洛谷P3177 题目大意: 给你一颗含n个点的树,让你选出k个黑点,其他都为白点。然后贡献为同颜色点之间两两路径和.最大化贡献。 k≤n≤2000k \leq n \leq 2000k≤n≤2000 题目思路: 1.首先定义状态 dp[i][j]dp[i][j]dp[i][j]为节点i,有j个黑点的最大值 这样以来,我们可以将一颗子树的黑点个数看作是背包的体积。然后二元组<子树中黑点个数,点对贡献>就代表着一个物品。对于每个子树来说,只能向根转移一种二元组(黑点个数0~min(子树大小,k)

qq_35577488的博客 451

树形DP总结

树形DP总结

ZhuRanCheng的博客 747

树上背包(P2014 [CTSC1997] 选课)

树上背包问题指的是在树形结构上进行动态规划,结合背包问题的思想,通常用于解决子树资源分配或依赖选择的问题。这类问题通常涉及节点间的依赖关系,需要在树上进行状态转移。

2401_88124440的博客 466

树形背包例题及实现技巧

一、选课(模板题) 在大学里每个学生,为了达到一定的学分,必须从很多课程里选择一些课程来学习,在课程里有些课程必须在某些课程之前学习,如高等数学总是在其它课程之前学习。现在有门功课,每门课有个学分,每门课只有一门或没有直接先修课(若课程是课程的先修课即只有学完了课程,才能学习课程)。一个学生要从这些课程里选择门课程学习,问他能获得的最大学分是多少? 第一行有两个整数,(,)。接下来的行,第行包...

pig_dog_baby的博客 4023

深谈树形背包(有依赖的背包)

是一种背包问题的变体,与传统的背包问题不同的是,物品之间存在一定的层次结构,形成了一棵树。:要选一个物品,必须选它的父节点物品给他父结点保留v[t]的背包容量即可,剩下的V-v[t]给它的子节点,子节点又是父节点,它又有子节点,继续递归下去,max去寻找最大价值。这个树形结构选择才出现了有依赖,选这个物品,就要确保它的所有结点都被选择了,才能选择它,有点类似于数据结构中的。

闻道有先后,术业有专攻 1657
上一篇: [主席树维护HASH] Codechef. Cloning
下一篇: [数论] Codeforces819D. Mister B and Astronomers
LowestJN
博客等级 码龄10年 76粉丝 422原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值