POJ 1155 (树形DP+背包+优化)
题目链接: http://poj.org/problem?id=1155
题目大意:电视台转播节目。对于每个根,其子结点可能是用户,也可能是中转站。但是用户肯定是叶子结点。传到中转站或是用户都要花钱,如果是用户,则还可以收钱。问在不亏本的前提下最多能有多少个用户看到节目。
解题思路:
比较麻烦的树形背包。首先cost=1。
花的钱权在边,收的钱权在点,且是叶子结点。所以首先可以对叶子结点进行预处理。
用dp[i][j]表示在i点时传播j个用户(包含自身),则dp[n-m-1~n][1]=每个用户缴费。
这样在dfs的时候就可以专心处理边权问题。两个for循环这么写:
for(f...j...cost)
for(0...k...j)
则转移方程就是dp[i][j]=max(dp[i][j],dp[i][j-k]+dp[t][k]-e[a].w);
这里之所以是f而不是f+1,是因为中转站不是用户,不需要cost。f+=dfs(t)。
对于如何知道在不亏本的情况下的最多用户,在dfs之后,从dp[1][m..0]开始找一个大于0的最大m值。
如果你熟悉传统的树形背包的话,就会发现这里不能每次都使用最大背包容量m循环了,不然会TLE,原因是这题m比较大,每次都从m开始不T就怪了。
所以必须采用这种cost=1时特殊的当前最大容量f。
#include "cstdio"
#include "iostream"
#include "cstring"
using namespace std;
#define maxn 3005
#define inf 0x3f3f3f3f
struct Edge
{
int to,next,w;
}e[maxn];
int leaf[maxn],dp[maxn][maxn],get[maxn],head[maxn];
int n,m,k,v,w,tol;
void addedge(int u,int v,int w)
{
e[tol].to=v;
e[tol].next=head[u];
e[tol].w=w;
head[u]=tol++;
}
int dfs(int root)
{
if(head[root]==-) return ;
int i=root,f=,cost=;
for(int a=head[root];a!=-;a=e[a].next)
{
int t=e[a].to;
f+=dfs(t);
for(int j=f; j>=cost; j--)
for(int k=; k<=j; k++)
dp[i][j]=max(dp[i][j],dp[i][j-k]+dp[t][k]-e[a].w);
}
return f;
}
int main()
{
//freopen("in.txt","r",stdin);
memset(head,-,sizeof(head));
scanf("%d%d",&n,&m);
for(int i=;i<=n-m;i++)
{
scanf("%d",&k);
for(int j=;j<=k;j++)
{
scanf("%d%d",&v,&w);
addedge(i,v,w);
}
}
for(int i=; i<=n; i++)
for(int j=; j<=n; j++)
dp[i][j]=-inf;
for(int i=n-m+;i<=n;i++) {scanf("%d",&get[i]);dp[i][]=get[i];}
dfs();
for(int i=m;i>=;i--)
{
if(dp[][i]>=)
{
printf("%d\n",i);
break;
}
}
}
13540208 | neopenx | 1155 | Accepted | 33704K | 157MS | C++ | 1322B | 2014-10-18 00:48:42 |
POJ 1155 (树形DP+背包+优化)的更多相关文章
- POJ 1155 树形DP
题意:电视台发送信号给很多用户,每个用户有愿意出的钱,电视台经过的路线都有一定费用,求电视台不损失的情况下最多给多少用户发送信号. 转自:http://www.cnblogs.com/andre050 ...
- poj 1947(树形DP+背包)
Rebuilding Roads Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 10663 Accepted: 4891 ...
- Ural 1018 (树形DP+背包+优化)
题目链接: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=17662 题目大意:树枝上间连接着一坨坨苹果(不要在意'坨'),给 ...
- Fire (poj 2152 树形dp)
Fire (poj 2152 树形dp) 给定一棵n个结点的树(1<n<=1000).现在要选择某些点,使得整棵树都被覆盖到.当选择第i个点的时候,可以覆盖和它距离在d[i]之内的结点,同 ...
- URAL_1018 Binary Apple Tree 树形DP+背包
这个题目给定一棵树,以及树的每个树枝的苹果数量,要求在保留K个树枝的情况下最多能保留多少个苹果 一看就觉得是个树形DP,然后想出 dp[i][j]来表示第i个节点保留j个树枝的最大苹果数,但是在树形过 ...
- 树形dp空间优化(dfn)
树形dp空间优化 介绍 有时题目会告诉我们n叉树的最大层数,或者给出一个完全n叉树树,直接做树形dp会爆空间时,就可以用这个优化方法. 多数树形dp都是先dfs到子树,再合并到根上,显然当合并到根上时 ...
- POJ 1155 树形背包(DP) TELE
题目链接: POJ 1155 TELE 分析: 用dp[i][j]表示在结点i下最j个用户公司的收益, 做为背包处理. dp[cnt][i+j] = max( dp[cnt][i+j ...
- Vijos 1180 (树形DP+背包)
题目链接: https://vijos.org/p/1180 题目大意:选课.只有根课选了才能选子课,给定选课数m, 问最大学分多少. 解题思路: 树形背包.cost=1. 且有个虚根0,取这个虚根也 ...
- BZOJ.1017.[JSOI2008]魔兽地图(树形DP 背包DP)
题目链接 树形DP,考虑子节点对父节点的贡献. 设f[x][i][j]表示当前为x,用i个x去合成上一层装备,花费为j的最大价值. 由子节点转移时 是一个分组背包,需要一个辅助数组g[i][j]表示前 ...
随机推荐
- iOS的 context 和Android 中的 canvas
ios 想要绘图,要用到CGContextRef类.最基本的用法是在- (void)drawRect:(CGRect)rect 函数中绘制. Android 中要用到Canvas类.最基本的用法是在 ...
- iOS 中的frame,bounds,center,transform关联
这里有一篇好文章 http://www.winddisk.com/2012/06/07/transform/ 先看几个知识点,UIView 的frame,bounds,center,transform ...
- DisJSet:Find them, Catch them(POJ 1703)
抓住他们! 题目大意:两个黑社会帮派,互相打架,现在你很多条信息,要你确定两个人是否属于不同帮派 这题很有趣,题目不是直接给你两个人是否是一个帮派的,他给你的是不同帮派的,也就是给你很多个不同的要你找 ...
- css样式自适应,支持数字
td加上style="word-break: break-all;word-wrap: break-word;"样式即可
- 爱情之路(codevs 2070)
题目描述 Description yh非常想念他的女朋友小y,于是他决定前往小y所在的那块大陆. 小y所在的大陆共有n个城市,m条双向路,每条路连接一个或两个城市.经过一条路ei需要耗费时间ti.此外 ...
- Session入门
Session是运行在服务器的,不可造假,例如:医生需要一个私人账本,记录病人编号和身份的对应关系.由于身份证无法造假,所以能够保证信息不被假冒.两点:身份证无法造假,这个身份证就可以唯一标识这个用户 ...
- (九)STM32之AFIO
也许你以为IO和AFIO是很简单的,事实上有几个误区可能很多人都没注意过,当你只用现成的开发板来学习的时候,别人已经帮你做好了资源分配,所有的外设功能学习都是照着别人给你的例程去做的,这才没让你觉得奇 ...
- WebService之CXF框架
本文主要包括以下内容 ant工具的使用 利用cxf实现webservice cxf与spring整合 ajax访问webservice ant 工具 1.为什么要用到ant这个工具呢? Ant做为一种 ...
- p235习题3
- IntelliJ IDEA快捷键和常用设置
一 快捷键的使用 1.文本编辑删除 ctr + y复制 ctr + D2.智能提示提示 ctr + space智能提示 ctr + shift + space完成当前语句 ctr + ...