解题策略·状态精简

状态精简是一类极其重要的方法,在动态规划、组合计数中的应用尤为普遍。先来看一些习题:

1.LA 4380(CERC 2008) Counting Heaps

题意:给出一颗$n(1 \leq n \leq 500000)$个结点的有根树,要求给结点编号为$1 \sim n $,使得不同结点的标号不同,且每个非根结点标号比父节点小(满足堆性质)。求方案总数除以$m$的余数$(2 \leq m \leq 10^9)$。当$n=5$时有如下$8$种方案。

分析:我们可以这样给结点分配编号:按照从小到大的顺序分配,最小的必然是树根,次小的分配给根的子结点中的某一个...。也就是给出一个满足父结点小于所有子树结点的一个拓扑序,那么维护一个下一次可以被分配为分配最小编号的结点队列,直到队列为空,初始状态只有根节点在队列中。这样遍历所有节点一次就找到了一个方案,方法可行但无效,复杂度太高。为什么?因为我们考虑得太细致了,把所有细节都兼顾的代价就是无法承受的复杂度,虽然方法对于答案是充分的,但是却并不必要。计数并不等同于枚举。更好的方法?深入挖掘问题的实质。实际上该问题是有局部性质的:我们固定每棵子树的所有结点编号的集合,那么总的方案数就是确定的,因为满足局部拓扑序必然不会破坏整体,而局部的相对顺序已经由子树的形态给出,我们不需要知道赋给每个结点的编号是具体是几,而只需要知道它是第几大。我们设$f(i)$为根节点为$i$的子树在所有候选编号集合固定的情况下的方案数,那么考虑$i$的一个子节点$j$,我们用$g(u)$表示以$u$为根结点子树的大小,那么$j$子树的编号可取集合总数为$\textrm{C}_{g(i) - 1}^{g(j)}$,于是$j$子树的总方案数为$\textrm{C}_{g(i) - 1}^{g(j)}f(j)$,这样剩下部分(将$j$子树从$i$子树中删去)的总方案数与当前$j$子树的总方案数的乘积即为$i$子树的总方案数。即有$f(i)=f(j)\textrm{C}_{g(i) - 1}^{g(j)}f(i\setminus j)$其中$f(i\setminus g)$表示将$j$子树从$i$子树中删去得到的子树。我们设$i$子树有$p$个子结点,第$i$个为$n_i$,应用上式可以得到$f(i)=\prod_{j=1}^{p}{f(n_j)\textrm{C}_{g(i)-1-\sum_{k<p}{g(n_k)}}^{g(n_j)}}$,于是$O(n)$时间即可解决。

时间: 2024-11-03 01:31:37

解题策略·状态精简的相关文章

《算法实战策略》-chaper19-队列、栈和双端队列

对于计算机专业的学生来说,他们一定会很熟悉一句话:程序设计 = 算法 + 数据结构.而根据笔者的理解,所谓程序设计其实就是为了编程解决实际问题,所谓算法是一种解决问题某种思维的方法,但是思维需要得到编程实践,这就需要基于数据结构.一个好的数据结构能够让我们更快更高效得处理数据,有些模拟性.数学背景并不深厚的的问题,仅仅基于高效的数据结构就可以解决.那么这一章节,我们就单独将队列.栈.双端队列拿出来,结合具体的题目,看看它们是如何灵活的运用到解题策略当中的. 考虑到笔者在<入门经典>和<啊

设计模式6(组合模式,模板方法,策略模式)

组合模式 将对象组合为"部分-整体"的层次结构,组合模式使得用户对单个对象和组合对象的使用统一的接口 关键在于抽象类的定义,为leaf 和composite提供了统一的接口 操作接口 添加leaf 删除leaf 获取特定leaf 装饰者模式 可以将装饰者支持组合模式需要的一些功能       享元模式   当组合模式中出现大量相似的组件对象并且状态可以从组件对象分离     迭代模式         访问者 在不修改原有对象结构的基础上为基添加新功能       职责链模式 其实现请求

数学解题的思维过程(来自网络)

数学解题的思维过程 数学解题的思维过程是指从理解问题开始,经过探索思路,转换问题直至解决问题,进行回顾的全过程的思维活动. 对于数学解题思维过程,G . 波利亚提出了四个阶段*(见附录),即弄清问题.拟定计划.实现计划和回顾.这四个阶段思维过程的实质,可以用下列八个字加以概括:理解.转换.实施.反思. 第一阶段:理解问题是解题思维活动的开始. 第二阶段:转换问题是解题思维活动的核心,是探索解题方向和途径的积极的尝试发现过程,是思维策略的选择和调整过程. 第三阶段:计划实施是解决问题过程的实现,它

【海龟汤策略】反趋势交易策略源代码分享(基于BOTVS)

策略介绍: 海龟之汤,简称“龟汤”,是个与海龟交易法则相反的交易策略,它利用了跟势交易(特别是海龟方式)在很多假突破方面的缺陷来获利(把海龟做成汤吃掉).上世纪八十年代早期,有个非常著名的交易员团体——叫做“海龟”.缔造了交易传奇的市场大师理查德·丹尼斯在训练一组新交易员的时候起了这个有趣的名字.因为理查德相信,培训交易员,其实就像新加坡人养海龟一样.这个交易方法被称作海龟方法,这个简单的趋势跟随技巧方法曾令他们的导师理查德取得了巨大的成功. 二十多年过去了,海龟方法现在已不再是个秘密,很多人已

F100-M-G 基本域间策略配置

设备存在两种类型的安全域,分别是: Local:本地域 Trust:安全域 DMZ:应用域 Untrust:不安全域 Management:管理域 • 缺省安全域: 不需要通过命令zone name 配置就已经存在的安全域,名称为:Local.Trust.DMZ.Untrust 和Management. • 非缺省安全域: 通过命令 zone name 创建的安全域. 设备安全域之间的互访策略存在两种状态, 一种是优先级访问策略状态, 一种是无优先级访问策略状态. (1) 优先级访问策略状态,安

noip2003提高组题解

这一年的前三题虽然难度不高,但是第二题极为繁琐,想在考场上用较短的时间拿到第二题的分数难上加难.所以必须要调整策略,争取拿其他三题的分数.第四题是比较普通的搜索题,分数比较好拿,但是很容易想成树形DP,就只能拿30~50分. ? 第一题:神经网络 模拟 有几个注意点: 输入层(即第一层)的结点的U(阈值)是没有用的: 题目说输出「最后状态非零的输出层神经元状态」,但实际上输出的是状态大于0的值. 由于没有注意到神经元只有在兴奋状态时才会向下传送信号,所以WA了1次. ? 第二题:侦探推理 模拟+

Leetcode分类解析:组合算法

Leetcode分类解析:组合算法 所谓组合算法就是指:在解决一些算法问题时,需要产生输入数据的各种组合.排列.子集.分区等等,然后逐一确认每种是不是我们要的解.从广义上来说,组合算法可以包罗万象,甚至排序.各种搜索算法都可以算进去.最近读<The Algorithm Design Manual>时了解到这种归类,上网一查,甚至有专门的书籍讲解,而且Knuth的巨著TAOCP的第四卷就叫组合算法,看来还真是孤陋寡闻了!于是最近着重专攻了一下Leetcode中所有相关题目,在此整理一下学习心得.

数据结构应用案例——栈结构用于8皇后问题的回溯求解

[说明]本文来自由周世平老师主编的<C语言程序设计>教材.我作为参编人员执笔了第7.8章."第8章 问题求解与算法"中"8.6.1 回溯法"以8皇后问题的求解为例,介绍了回溯法的解题过程.这个解决方案中用到了"栈",引用至此,作为栈应用的例子.需要说明的是,教材面向程序设计初学者,并全文中并未提出过任何关于"栈"的描述.这样做,隐藏了术语,减少初学者的认知难度.对于数据结构的学习者而言,由于知识面的扩大,却用不着回

【资料】国家集训队论文集(1999~2014)

本文版权归ACShiryu和acvay所有,如转载请注明原作者. 国家集训队1999论文集 1.陈宏:<数据结构的选择与算法效率--从IOI98试题PICTURE谈起> 2.来煜坤:<把握本质,灵活运用--动态规划的深入探讨> 3.齐鑫:<搜索方法中的剪枝优化> 4.邵铮:<数学模型的建立.比较和应用> 5.石润婷:<隐蔽化.多维化.开放化--论当今信息学竞赛中数学建模的灵活性> 6.杨帆:<准确性.全面性.美观性--测试数据设计中的三要素