题目大意:给定一棵 N 个节点的有根树,1 号节点为根节点,叶子节点有点权,每条边有边权,每经过一条边都减去该边权,每经过一个节点都加上该点权,求在保证权值和为非负数的前提下最多能经过多少个叶子节点。

题解:\(dp[u][i]\) 表示在以 u 为根节点的子树中,经过 i 个叶子节点的最大权值和,则有状态转移方程:$$dp[u][i]=max(dp[u][i],dp[v][k]+dp[u][i-k])$$。

一般前提为第一要素,作为要最优化的值,将要求的最优化的值最为附加属性,最后在满足前提的条件下遍历附加属性求出答案。

update on 2019.5.24

学习到了树上背包问题的上下界优化。

一开始做这道题肯定会觉得复杂度分析很奇怪,即:三个 for 循环竟然过了3000的数据量。

最后看了大佬的博客终于明白了,复杂度从严格意义上来说就是 \(O(n^2)\) 的。

感性证明如下:

我们实现的 dfs 过程可以看作是子树维护的信息合并的过程。在这个过程中,发现任意两个点为根节点的子树信息均发生且仅发生了一次合并。而对于任意两个点的信息合并仅发生在这两个节点的 lca 处,因此时间复杂度为 \(O(n^2)\)。

稍微严谨一点的证明如下:

\[T_u=\sum\limits_{fa[v]=u}T_v+f(u)
\]

首先证明对于子树合并的过程复杂度是 \(O(sz[u]^2)\) :

\[\begin{aligned} f_{u} &=1+\left(1+s i z\left[v_{1}\right]\right) \times \operatorname{siz}\left[v_{1}\right]+\left(1+\operatorname{siz}\left[v_{1}\right]+s i z\left[v_{2}\right]\right) \times \operatorname{siz}\left[v_{2}\right]+\cdots+\operatorname{siz}[u] \times \operatorname{siz}\left[v_{k}\right] \\ &\le 1+\sum_{fa\left[v_{i}\right]=u} \operatorname{siz}\left[v_{i}\right] \times(\operatorname{siz}[u]+1) \\ &=O(\operatorname{siz}[u]^{2}) \end{aligned}
\]

再证明前面子树的和式也是 \(O(sz[u]^2)\):

利用数学归纳法可知,每个子树都是 \(O(sz[v]^2)\) 的,那么在合并的过程中,利用均值不等式(平方的和大于和的平方)可直接证出。

因此,总的时间复杂度为 \(O(n^2)\)。

代码如下

#include <bits/stdc++.h>
using namespace std;
const int maxn=3010; struct node{
int nxt,to,w;
}e[maxn<<1];
int tot,head[maxn];
inline void add_edge(int from,int to,int w){
e[++tot]=node{head[from],to,w},head[from]=tot;
} int n,m,val[maxn],dp[maxn][maxn]; void read_and_parse(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n-m;i++){
int k;scanf("%d",&k);
for(int j=1;j<=k;j++){
int to,w;scanf("%d%d",&to,&w);
add_edge(i,to,w);
}
}
for(int i=n-m+1;i<=n;i++)scanf("%d",&val[i]);
memset(dp,0xcf,sizeof(dp));
} int dfs(int u){
dp[u][0]=0;
if(u>n-m){dp[u][1]=val[u];return 1;}
int sum=0;
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].to;
int t=dfs(v);sum+=t;
for(int j=sum;j;j--)
for(int k=1;k<=t;k++)
dp[u][j]=max(dp[u][j],dp[u][j-k]+dp[v][k]-e[i].w);
}
return sum;
} void solve(){
dfs(1);
int ans=0;
for(int i=m;i;i--)if(dp[1][i]>=0){ans=i;break;}
printf("%d\n",ans);
} int main(){
read_and_parse();
solve();
return 0;
}

【洛谷P1273】有线电视网的更多相关文章

  1. 洛谷 P1273 有线电视网

    2016-05-31 13:25:45 题目链接: 洛谷 P1273 有线电视网 题目大意: 在一棵给定的带权树上取尽量多的叶子节点,使得sigma(val[选择的叶子节点])-sigma(cost[ ...

  2. 洛谷 P1273 有线电视网(树形背包)

    洛谷 P1273 有线电视网(树形背包) 干透一道题 题面:洛谷 P1273 本质就是个背包.这道题dp有点奇怪,最终答案并不是dp值,而是最后遍历寻找那个合法且最优的\(i\)作为答案.dp值存的是 ...

  3. 洛谷P1273 有线电视网 (树上分组背包)

    洛谷P1273 有线电视网 题目描述 某收费有线电视网计划转播一场重要的足球比赛.他们的转播网和用户终端构成一棵树状结构,这棵树的根结点位于足球比赛的现场,树叶为各个用户终端,其他中转站为该树的内部节 ...

  4. 【题解】洛谷P1273 有线电视网(树上分组背包)

    次元传送门:洛谷P1273 思路 一开始想的是普通树形DP 但是好像实现不大好 观摩了一下题解 是树上分组背包 设f[i][j]为以i为根的子树中取j个客户得到的总价值 我们可以以i为根有j组 在每一 ...

  5. 洛谷——P1273 有线电视网

    P1273 有线电视网 题目大意: 题目描述 某收费有线电视网计划转播一场重要的足球比赛.他们的转播网和用户终端构成一棵树状结构,这棵树的根结点位于足球比赛的现场,树叶为各个用户终端,其他中转站为该树 ...

  6. C++ 洛谷 P1273 有线电视网 题解

     P1273 有线电视网  很明显,这是一道树形DP(图都画出来了,还不明显吗?) 未做完,持续更新中…… #include<cstdio> #include<cstring> ...

  7. 洛谷P1273 有线电视网 树上分组背包DP

    P1273 有线电视网 )逼着自己写DP 题意:在一棵树上选出最多的叶子节点,使得叶子节点的值 减去 各个叶子节点到根节点的消耗 >= 0: 思路: 树上分组背包DP,设dp[u][k] 表示 ...

  8. 洛谷P1273 有线电视网 【树上分组背包】

    题目描述 某收费有线电视网计划转播一场重要的足球比赛.他们的转播网和用户终端构成一棵树状结构,这棵树的根结点位于足球比赛的现场,树叶为各个用户终端,其他中转站为该树的内部节点. 从转播站到转播站以及从 ...

  9. 洛谷P1273 有线电视网【树形dp】

    题目:https://www.luogu.org/problemnew/show/P1273 题意:一棵树,叶子节点是用户,每天边有一个权值表示花费,每一个用户有一个值表示他们会交的钱. 问在不亏本的 ...

  10. 洛谷 P1273 有线电视网(dp)

    /* 想了半天没想出状态 自己还是太弱了 QAQ 题目问的是最多供给多少户 一般想法是把这个值定义为状态量 没想出来QAQ....看了看题解的状态 很机智.... f[i][j]表示i的子树 选了j个 ...

随机推荐

  1. 【下一代核心技术DevOps】:(四)私有镜像库阿里云Docker服务使用

    1.使用阿里云镜像库有很多优点 稳定可靠,阿里技术,放心使用. 国内cdn多节点加速,下载速度非常快 可以和阿里云Git代码集成,不需要第三方CI工具,当然带的自动构建服务也可以和其他的Git库集成, ...

  2. echarts柱状图标签显示不完全的问题

    echarts 柱状图当x轴标签数目超过一定数目时在小尺寸设备上第一个和最后一个标签不显示(不是重叠),axisLabel设置interval:0也不起作用; 解决办法: 这个问题存在于4.0版本以上 ...

  3. Linux ugo 权限

    Linux 系统中文件的 ugo 权限是 Linux 进行权限管理的基本方式.本文将介绍 ugo 权限的基本概念.说明:本文的演示环境为 ubuntu 16.04. 文件的所有者和组 Linux 文件 ...

  4. 我的AutoHotkey脚本

    #NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases. ; #Warn ; En ...

  5. 添加php的memcached扩展模块

    memcached服务直接用yum安装[root@localhost ~]# yum install memcached 然后启动memcache服务,启动多个实例[root@localhost ~] ...

  6. db2修改最大连接数

    查看当前连接数,sample为数据库名db2 list applications for db sample db2 list applications for db sample show deta ...

  7. github的使用心得

    我的github地址:https://github.com/gaino1/test GitHub 是一个用于使用Git版本控制系统的项目的基于互联网的存取服务. GitHub可以托管各种git库,并提 ...

  8. 个人项目junit4测试

    一.题目简介 用java编写一个程序,模拟ATM柜员机. 二.源码的github链接 www.github.com/liuxianchen/test 三.所设计的模块测试用例.测试结果截图 四  心得 ...

  9. Issue: business key in a call activiti

    https://community.alfresco.com/thread/221280-business-key-in-a-call-activity 这个帖子有一些讨论和回复. https://c ...

  10. Wordpress 更新时 不输入ftp相关信息的方法

    From 百度知道 我自己机器上面的处理过程为: cd /usr/share/nginx/html vim wp-config.php 在配置文件里面插入这三行 define("FS_MET ...