有线电视网 题解 动态规划详细分析

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/NUpMan/article/details/80323361

题目

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

从转播站到转播站以及从转播站到所有用户终端的信号传输费用都是已知的,一场转播的总费用等于传输信号的费用总和。

现在每个用户都准备了一笔费用想观看这场精彩的足球比赛,有线电视网有权决定给哪些用户提供信号而不给哪些用户提供信号。

写一个程序找出一个方案使得有线电视网在不亏本的情况下使观看转播的用户尽可能多。

思考

先从最简单的思路开始,可以直接枚举所有可能,即列出所有对用户的取舍策略,并对每一种可能分别计算费用,子树A计算费用的时间花费可用递归式
cost(A) = cost(A.subtree[1]) + cost(A.subtree[2]) +…
表达,最后取使费用大于0且用户数最多的策略,那么假设用户数为n,所有节点数为m,则算法的时间复杂度为O(m*2n),这在用户数稍大的情况下便是不可行的。

但稍加思索便可以发现,其实枚举算法中存在大量无必要的重复运算。比如考虑存在用户A,B,C的情况,假设B,C属于同一颗子树,而A的取值不影响该子树的花费,那么该子树的花费直接由B,C决定,也就是只存在4种不同情况,而原来的算法并未考虑到这点,对8种所有的情况分别调用了该子树的cost计算。那么显然出现了不是必须调用cost计算的情况,这里可以直接用一个向量(Subtree, B, C, cost)记录下已计算过的情况,这样之后可以对该子树,通过B,C取值情况直接求值。
尽管通过增加额外的空间开销换到了时间上的改善,不过可以直觉上确定出,其实时间复杂度还是O(2n),也就是并未有本质上的改善。

最后的改善是最为困难的,需要根据题意,确定出明显不需要计算的取舍策略,也就是,一些策略的计算结果能绝对优于另一些策略。可以确定出如下一条准则,
对同一颗子树,只需要考虑某一人数下开销最少的策略
那么向量的表示便可以改为(Subtree, NumOfPeople, CostMin),那么问题便变为了如何计算出这个向量。

现在有子树A,以及A的子树A.subtree[1] A.subtree[2]….,假设A的子树的所有相关向量皆已知。
显然可以各取一个向量,简单地将NumofPeople和CostMin分别相加得到一个新的向量(A, SumOfNum, SumofCost),而所有这样的向量中,取SumOfNum相同的所有向量分别进行比较就可以确定出(A, NumOfPeople, CostMin),为什么该向量只基于以(Subtree, NumOfPeople, CostMin)构成的集中,这问题可以用反证法解决。

计算新的向量的过程若是和最开始那样直接通过枚举解决,将会得到让人无法接受的复杂度,所以吸取了之前的经验,此处直接考虑如何选取最优的策略。
对于这个问题,可以确定出不记入某个子树的向量,剩余的其它子树的向量所构成的向量也必须是最优的,这样便成功剔除了无谓的非最优解的计算,而且可以采取递增的想法,先只考虑第一棵子树,得到一系列向量,再考虑第二棵子树,对基于第一棵子树所产生的向量进行优化。也便是构造出新的向量(A, NumOfSubtree, NumOfPeople, CostMin),而该向量的求解仅仅是遍历一遍所有子树的向量而已。

问题至此应该算是有了一个较为理想的解决。

熟悉的人应该一眼便能看出这不过是动态规划罢了,但用动态规划分析问题的原则我一直摸不清头脑,能够用来指导思考的概念也就仅限于“最优子结构”这句话,一直以来也只是就题论题,实在难以有掌握了的实感,所以写了这篇文章打算理清思路,可以看到我用了较为新颖的向量的概念来阐述思考,但效果也难说很好。最终还是依赖于基于经验的最佳策略论断,未能形成切实有效的方法。但这篇文章还是能给相关的问题分析提供了大致的框架,虽然最后还是要依赖于对已有模型的应用就是了。欢迎指出不足和错误。

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页