一、树形dp(4)有线电视网
来源:互联网 发布:dean martin知乎 编辑:程序博客网 时间:2024/05/03 07:25
源程序名 tele.???( pas, c, cpp)
可执行文件名 tele.exe
输入文件名 tele.in
输出文件名 tele.out
【问题描述】
某收费有线电视网计划转播一场重要的足球比赛。他们的转播网和用户终端构成一棵树
状结构,这棵树的根结点位于足球比赛的现场,树叶为各个用户终端,其他中转站为该树的
内部节点。
从转播站到转播站以及从转播站到所有用户终端的信号传输费用都是已知的,一场转播
的总费用等于传输信号的费用总和。
现在每个用户都准备了一笔费用想观看这场精彩的足球比赛,有线电视网有权决定给哪
些用户提供信号而不给哪些用户提供信号。
写一个程序找出一个方案使得有线电视网在不亏本的情况下使观看转播的用户尽可能
多。
【输入】
输入文件的第一行包含两个用空格隔开的整数 N 和 M,其中 2≤N≤3000, 1≤M
≤N-1, N 为整个有线电视网的结点总数, M 为用户终端的数量。
第一个转播站即树的根结点编号为 1,其他的转播站编号为 2 到 N-M,用户终端编号
为 N-M+1 到 N。
接下来的 N-M 行每行表示—个转播站的数据,第 i+1 行表示第 i 个转播站的数据,其
格式如下:
K A1 C1 A2 C2 … Ak Ck
K 表示该转播站下接 K 个结点(转播站或用户) ,每个结点对应一对整数 A 与 C, A 表
示结点编号, C 表示从当前转播站传输信号到结点 A 的费用。最后一行依次表示所有用户
为观看比赛而准备支付的钱数。
【输出】
输出文件仅一行,包含一个整数,表示上述问题所要求的最大用户数。
【样例输入】
tele.in
5 3
2 2 2 5 3
2 3 2 4 3
3 4 2
【样例输出】
tele.out
2
【样例解释】
如下图所示,共有五个结点。结点①为根结点,即现场
直播站,②为一
个中转站,③④⑤为用户端,共 M 个,编号从 N-M+1 到 N,
他们为观看比
赛分别准备的钱数为 3、 4、 2,从结点①可以传送信号到结点
②,费用为 2,
也可以传送信号到结点⑤,费用为 3(第二行数据所示),从
结点②可以传输信号到结点③,费用为 2。也可传输信号到结
点④,费用为 3(第三行数据所示),如果要让所有用户(③④⑤)都能看上比赛,则信号
传输的总费用为:
2+3+2+3=10,大于用户愿意支付的总费用 3+4+2=9,有线电视网就亏本了,而只让③
④两个用户看比赛就不亏本了。
分析:
用动态规划求解。状态这样定义,设F[A, M]为A结点下支持M个用户所能得到的最大赢利。转移方程为:
F[A, M]=Max{F[B1, M1]+F[B2, M2]+…+F[Bk, Mk] | Bi是A的子结点,M1+M2+…+Mk=M}
可以考虑将多叉数转换成二叉树来做,也可以考虑动态地分配内存。这样,空间复杂度约为O(n),时间复杂度为O(n2)。
代码:
const
oo = -30000;
MAX = 3000;
var
n,m : integer;
tablica,temp,veza,cijena : array[0..MAX, 0..MAX] of integer;
koliko,placa : array[0..MAX] of integer;
function korisnik(a : integer) : boolean;
begin
if (a >= n-m) then korisnik := true else korisnik := false;
end;
function maxi(a, b, c : integer) : integer;
begin
if ((a >= b) and (a >= c)) then maxi := a
else if ((b >= a) and (b >= c)) then maxi := b
else maxi := c;
end;
function dfs(cvor : integer) : integer;
var
i,j,k,dokle,ndokle,novi : integer;
begin
for i:=1 to m do
begin
tablica[cvor,i] := oo;
temp[cvor,i] := oo;
end;
tablica[cvor,0] := 0;
dokle := 0;
for i:=0 to koliko[cvor]-1 do
begin
novi := veza[cvor,i];
temp[cvor,0] := 0;
if (korisnik(novi)) then
begin
inc(dokle);
for j:=1 to dokle do
temp[cvor,j] := maxi(tablica[cvor,j], temp[cvor,j], tablica[cvor,j-1] - cijena[cvor,i] + placa[novi]);
end
else
begin
ndokle := dfs(novi);
inc(dokle, ndokle);
for j:=1 to dokle do
for k:=1 to ndokle do
if (j-k >= 0) then
temp[cvor,j] := maxi(tablica[cvor,j], temp[cvor,j], tablica[cvor,j-k] - cijena[cvor,i] + tablica[novi,k])
else break;
end;
for j:=0 to dokle do
begin
tablica[cvor,j] := temp[cvor,j];
temp[cvor,j] := oo;
end;
end;
dfs := dokle;
end;
var
f : text;
i,j,rjesenje : integer;
begin
assign(f, 'tele.in'); reset(f);
read(f, n, m);
for i:=0 to n-m-1 do
begin
read(f, koliko[i]);
for j:=0 to koliko[i]-1 do
begin
read(f, veza[i,j], cijena[i,j]);
dec(veza[i,j]);
end;
end;
for i:=n-m to n-1 do
begin
koliko[i] := 0;
read(f, placa[i]);
end;
close(f);
dfs(0);
rjesenje := m;
while (tablica[0,rjesenje] < 0) do dec(rjesenje);
assign(f, 'tele.out'); rewrite(f);
writeln(f, rjesenje);
close(f);
end.
- 一、树形dp(4)有线电视网
- 【树形dp】有线电视网
- 【luogu1273】有线电视网(树形DP)
- 洛谷 P1273 有线电视网 树形dp
- 洛谷P1273 有线电视网(DP,分组背包)
- 树形背包模版-洛谷P1273 有线电视网
- 洛谷1217 有线电视网 树上dp
- 有线电视网
- 有线电视网
- sdh概念与有线电视网(上)
- 【Luogu1273】有线电视网(动态规划)
- 有线电视网技术科普
- 洛谷P1273 有线电视网
- 洛谷1273 有线电视网
- 洛谷 P1273 有线电视网
- 洛谷1273有线电视网
- 洛谷P1273 有线电视网
- [洛谷1273] 有线电视网
- (Eclipse) 安装Subversion1.82(SVN)插件
- java基础==集合
- Linux常用命令大全
- vim 复制粘贴
- oracle clob ERROR org.hibernate.util.JDBCExceptionReporter - ORA-00932: 数据类型不一致: 应为 -, 但却获得 CLOB
- 一、树形dp(4)有线电视网
- mysql分表和分区详解
- 武大集训第三周总结(转)
- OSGI Buleprint(5)
- clang: error: no such file or directory和no input files错误问题
- Dalvik虚拟机中DexClassLookup结构解析
- iOS为什么Block的属性声明要用copy
- Scala 函数
- 苹果的TestFlight测试服务将推出新功能