洛谷 P1273 有线电视网(树形背包)
洛谷 P1273 有线电视网(树形背包)
干透一道题
题面:洛谷 P1273
本质就是个背包。这道题dp有点奇怪,最终答案并不是dp值,而是最后遍历寻找那个合法且最优的\(i\)作为答案。dp值存的是当前状态下的成本,所以合法情况即当成本值大于等于0,不亏本的时候。
因为dp维护的是成本,并且按照背包思想,存在让这个用户接入和不让这个用户接入两种决策,类比背包,所以状态转移方程容易得到原始方程:
\]
\(dp[s][i][j]\)表示当前节点\(s\)的前\(i\)个儿子中选取\(j\)个用户的成本,决策当前儿子接入\(k\)个用户。但是这里我们可以像01背包那样优化一维\(i\),只要我们递增遍历\(i\),递减遍历\(j\)即可,因为这样\(i-1\)轮的\(dp[s][i-1][j-k]\)状态才没有被第\(i\)轮的\(dp[s][i][j-k]\)状态覆盖,并且\(dp[w][k]\)最终的值就是\(dp[w][size_w][k]\)。
最终二维的dp方程:
\]
192ms AC Code:
#include <cstdio>
using namespace std;
#define MAXN 3003
#define MAX(A,B) ((A)>(B)?(A):(B))
#define INF 0x3ffffff
struct e{
int w,v,nxt;
} edge[10000010]; //边数一定要开大!
int dp[MAXN][MAXN],head[MAXN],sz[MAXN];
int n,m,cnt_e;
inline void adde(int u, int v, int w){
edge[++cnt_e].w=w;
edge[cnt_e].v=v;
edge[cnt_e].nxt=head[u];
head[u]=cnt_e;
}
int solve(int x, int fa){
if(x>=n-m+1&&x<=n) //是否为用户端
return sz[x]=1;
for(register int i=head[x];i;i=edge[i].nxt){ //”递增”遍历儿子i
sz[x]+=solve(edge[i].v, x); //树形dp通常自下而上更新
for(register int j=sz[x];j>=0;--j) //枚举状态
for(register int k=0;k<=sz[edge[i].v];++k) //枚举决策,当前儿子取几个用户
dp[x][j]=MAX(dp[x][j], dp[x][j-k]+dp[edge[i].v][k]-edge[i].w);
//dp[s][i][j]=max{dp[s][i-1][j-k]+dp[w][size_w][k]-cost[s][w]} 原始状态转移方程
}
return sz[x];
}
int main() {
scanf("%d %d", &n, &m);
for(register int i=0;i<=n;i++)
for(register int j=0;j<=m;j++)
dp[i][j]=-INF;
for (int i=1;i<=n;i++) dp[i][0]=0; //注意初始化!
for(int i=1;i<=n-m;++i){
int sz;
scanf("%d", &sz);
for(int j=1;j<=sz;++j){
int a,c;
scanf("%d %d", &a, &c);
adde(i, a, c); //链式前向星建边
}
}
for(int i=n-m+1;i<=n;++i)
scanf("%d", &dp[i][1]);
solve(1,0);
for(register int i=m;i>=0;--i) //递减遍历找到第一个合法值
if(dp[1][i]>=0){
printf("%d\n", i);
break;
}
return 0;
}
需要注意:
- 链式前向星边数不是\(N\),一定要开大
- dp的遍历顺序一定要正确,因为你已经优化了一维\(i\)
- 用户端支付的钱\(w\)应该表示为\(dp[n][1]=w\)
- dp一定要结合dp方程初始化
洛谷 P1273 有线电视网(树形背包)的更多相关文章
- 洛谷P1273 有线电视网 (树上分组背包)
洛谷P1273 有线电视网 题目描述 某收费有线电视网计划转播一场重要的足球比赛.他们的转播网和用户终端构成一棵树状结构,这棵树的根结点位于足球比赛的现场,树叶为各个用户终端,其他中转站为该树的内部节 ...
- 洛谷 P1273 有线电视网
2016-05-31 13:25:45 题目链接: 洛谷 P1273 有线电视网 题目大意: 在一棵给定的带权树上取尽量多的叶子节点,使得sigma(val[选择的叶子节点])-sigma(cost[ ...
- 【题解】洛谷P1273 有线电视网(树上分组背包)
次元传送门:洛谷P1273 思路 一开始想的是普通树形DP 但是好像实现不大好 观摩了一下题解 是树上分组背包 设f[i][j]为以i为根的子树中取j个客户得到的总价值 我们可以以i为根有j组 在每一 ...
- 洛谷P1273 有线电视网 树上分组背包DP
P1273 有线电视网 )逼着自己写DP 题意:在一棵树上选出最多的叶子节点,使得叶子节点的值 减去 各个叶子节点到根节点的消耗 >= 0: 思路: 树上分组背包DP,设dp[u][k] 表示 ...
- 洛谷——P1273 有线电视网
P1273 有线电视网 题目大意: 题目描述 某收费有线电视网计划转播一场重要的足球比赛.他们的转播网和用户终端构成一棵树状结构,这棵树的根结点位于足球比赛的现场,树叶为各个用户终端,其他中转站为该树 ...
- C++ 洛谷 P1273 有线电视网 题解
P1273 有线电视网 很明显,这是一道树形DP(图都画出来了,还不明显吗?) 未做完,持续更新中…… #include<cstdio> #include<cstring> ...
- 洛谷P1273 有线电视网 【树上分组背包】
题目描述 某收费有线电视网计划转播一场重要的足球比赛.他们的转播网和用户终端构成一棵树状结构,这棵树的根结点位于足球比赛的现场,树叶为各个用户终端,其他中转站为该树的内部节点. 从转播站到转播站以及从 ...
- [洛谷P1273] 有线电视网
类型:树形背包 传送门:>Here< 题意:给出一棵树,根节点在转播足球赛,每个叶子节点是一个观众在收看.每个叶子结点到根节点的路径权值之和是该点转播的费用,每个叶子节点的观众都会付val ...
- 洛谷 P1273 有线电视网 题解
题面 按照常见树形背包定义状态:设dp[u][j]表示在以u为根的子树中,选择j个客户所能获得的最大收益. 状态转移:dp[u][j]=max(dp[u][j-k],dp[v][k]-w(u,v)); ...
随机推荐
- yum 系列(一) yum 和 rpm 常用命令
yum 系列(一) yum 和 rpm 常用命令 一.yum 常用命令 yum 命令:http://man.linuxde.net/yum yum 是在 Fedora 和 RedHat 以及 SUSE ...
- linux网络编程模型
1.编程模型 Linux网络编程模型是基于socket的编程模型
- 打开Android Studio时报Unable to access Android SDK add-on list
第一次安装Android studio时候弹出unable to access android sdk add-on list原因是你电脑没有SDK而且你下载的android studio又是不带SD ...
- git 回退到某个特定提交
1.先用git log commit aba290c570d3894f4f39a1fdf52aa512c0231525 Author: huzhengbo <@qq.com> Date: ...
- fakeapp, faceswap, deepfacelab等deepfakes换脸程序的简单对比
https://deepfakes.com.cn/index.php/95.html https://www.cnblogs.com/zackstang/p/9011753.html
- Elasticsearch 安装的时候,Unsupported major.minor version 51.0问题的解决
Elasticsearch安装的时候报错 bootstrap/Elasticsearch : Unsupported major.minor version 51.0 网上一般说的方法是,升级或者降级 ...
- jenkins yum 安装
jenkins yum 安装 jenkins 用过yum的方式安装:服务的启动和关闭等管理会很方便,版本升级也会变的很容易. 参考官方的说明:https://wiki.jenkins-ci.org/d ...
- 浅谈 温故知新——HTML5!
古人有云:温故而知新.活到老,学到老,作为一枚前端的程序猿,不停的学习能够让我们对我们的技术有一个更加丰富的认识.这几天,项目已经完成,但我发现自己的知识体系存在一些短板,特别是在H5方面,所以我又回 ...
- TestNG参数化之@Parameters传参
通过TestNG实现参数话常用两种方式,一种是借助 @Parameters读取testng.xml中参数,一种是使用@DataProvider注解传参. 此次主要讲解XML传参,语法:在java类中定 ...
- k8s rc
RC是用来管理Pod的,每个RC由一个或多个Pod组成:在RC被创建之后,系统将会保持RC中的可用Pod的个数与创建RC时定义的Pod个数一致,如果Pod个数小于定义的个数,RC会启动新的Pod,反之 ...