洛谷 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)); ...
随机推荐
- python 多线程简介
Thread类定义了以下常用方法与属性: Thread.getName() \Thread.setName():老方式用于获取和设置线程的名称,官方建议用Thread.name替代 Thread.id ...
- Text Relatives II
[Text Relatives II] When your app determines that the user has requested the edit menu—which could b ...
- 使用windows server2012时FileZilla客户端连接时报150 Opening data channel for directory listing of "/" 响应:425 Can't open data connection
425 Can't open data connection 和 读取目录列表失败 问题解决 这个问题主要是由于使用Passive Mode模式造成的,解决这个问题很简单: 1.在ftp服务软件中设置 ...
- Gym 101201G Maximum Islands (最大独立集)
题意:给定一个图,L代表陆地,W代表水,C表示不确定,问你最多有多少岛. 析:首先给定的L周围必须是是W,只有这样才是最优的,因为如果是L,那么还得有另外的W来包围,不是最优的,那么剩下的就剩下C了, ...
- Oracle E-Business Suite并发处理机制(Current Processing)
2012年写过一篇关于Oracle E-Business Suite并发管理器的文章,回头看之前总结的内容还是比较单薄,很多点没说到,最近在看这块的内容,索性再写一篇稍微完整的文章来. Oracle ...
- Spring @SCHEDULED(CRON = "0 0 * * * ?")实现定时任务
Spring配置文件xmlns加入 xmlns:task="http://www.springframework.org/schema/task" xsi:schemaLocati ...
- 2、Orcal数据库创建第一个(管理员)连接
(注意这里第一个创建的是管理员连接也是我们的总连接,之后我们所有的其他新用户都要创建在它里面,所以它的一些属性我们在填写以及设置时需要注意!!!) 1.确认Orcal服务开启: 2.创建连接: 打开我 ...
- java学习笔记—国际化(41)
国际化:internationalization即I18N. 举例: 本科高校的网站,一般的都有中文和英文两种页面风格.因此将这种根据不同用户群体显示不同的页面风格的方式称之为页面的国际化. 翻译 V ...
- css3旋转动画
<!doctype html> <html> <head> <meta charset="utf-8"> <title> ...
- 面向对象之-@classmethod、@staticmethod和@classonlymethod的区别
实例方法.静态方法与类方法的含义 实例方法(普通方法)的含义就是需要类对象实例之后才能调用的方法,该方法的基本格式为: def test(self,*args,**kwargs): # 第一个参数必须 ...