决策树(特别是分类树)是一种数据结构,用于利用项目的特征将项目分类到不同的类别中。例如,每种动物要么是“可爱的”,要么不是。对于任何给定的动物,我们可以通过查看其特征并使用以下决策树来判断它是否可爱。
(0.2 furry (0.81 fast (0.3) (0.2) ) (0.1 fishy (0.3 freshwater (0.01) (0.01) ) (0.1) ) )
决策树是递归定义的。它始终包含一个根节点和一个权重。它还可以选择性地包含一个特征名称和两个子树,这两个子树本身也是决策树。
更正式地说,决策树使用以下语法定义:
tree ::= (weight [feature tree tree]) weight 是一个 0 到 1 之间的实数(包含 0 和 1) feature 是一个由 1 个或多个小写英文字母组成的字符串
方括号 [] 中的部分是可选的。圆括号 ()、weight 和 feature 是标记。任意两个标记之间至少会有一个空白字符,除非(可能)在左括号 '(' 之后或右括号 ')' 之前。空白字符包括空格 (' ') 和换行符 ('\n')。
为了计算动物可爱的可能性,我们从树的根节点开始,将概率 p 设为 1。在每个节点,我们将 p 乘以该节点的权重。如果该节点是叶子节点(没有子树),则停止,此时 p 的值就是该动物可爱的概率。否则,我们查看与该节点关联的特征。如果我们的动物具有此特征,则向下进入第一个子树并继续递归;如果它不具有此特征,则向下进入第二个子树并以相同方式继续。
例如,海狸是一种具有 furry 和 freshwater 两个特征的动物。我们从根节点开始,p 等于 1。我们将 p 乘以根节点的权重 0.2,并进入第一个子树,因为海狸具有 furry 特征。在那里,我们将 p 乘以 0.81,得到 p 等于 0.162。从那里我们继续向下进入第二个子树,因为海狸不具有 fast 特征。最后,我们将 p 乘以 0.2,最终得到 0.0324,这就是海狸可爱的概率。
给定一棵决策树和一系列带有特征的动物,你需要为每个项目返回该动物可爱的概率。
输入格式
输入的第一行包含一个整数 N,表示测试用例的数量。接下来是 N 个测试用例。
每个测试用例的描述以一行开始,包含一个整数 L,表示描述决策树的行数。接下来的 L 行包含上述格式的决策树。之后的一行包含 A,表示动物的数量。接下来的 A 行,每行包含一个动物的描述,格式如下:
animal n feature1 feature2 ... featuren
输出格式
对于每个测试用例,输出一行 "Case #x:",后跟恰好 A 行,每行对应一个动物,顺序与输入中的顺序相同。每一行应包含该动物可爱的概率。绝对误差或相对误差在 $10^{-6}$ 以内的答案将被视为正确。
数据范围
时间限制:4 秒。
内存限制:1 GB。
$1 \le N \le 100$
所有权重都在 0 到 1 之间(包含 0 和 1)。
所有权重仅由数字和一个小数点组成。
权重不会以小数点开头或结尾。
权重在小数点前不会有多于一个的 0。
所有动物名称和特征名称均由 1 到 10 个小写英文字母组成。
同一测试用例中的所有动物名称各不相同。
单个动物的所有特征名称各不相同。
决策树定义中的每一行(不包括换行符)最多包含 80 个字符。
子任务
小数据集 (10 分)
$1 \le L \le 10$
$1 \le A \le 10$
$0 \le n \le 5$
大数据集 (11 分)
$1 \le L \le 100$
$1 \le A \le 100$
$0 \le n \le 100$
样例
样例输入 1
1 1 3 (0.5 cool ( 1.000) (0.5 )) 2 anteater 1 cool cockroach 0
样例输出 1
Case #1: 0.5000000 0.2500000