問題 F 猜球球 XUPT2019 哈夫曼樹

2021-09-24 21:25:00 字數 1587 閱讀 9588

題目描述

六一到了,為了慶祝這個節日,好多商家都推出了很多好玩的小遊戲。tongtong看到了乙個猜球球的遊戲,有n種除了顏色之外完全相同的球,商家從中拿出來乙個球球放到了箱子裡,已知第i種顏色的球出現在箱子裡的概率為ai。tongtong可以用下面這種方法來確定箱子中球的顏色:向商家提出猜測:「是第x種顏色的球球或第y種顏色的球球或...........中的乙個」,商家會回答你的猜測是正確還是錯誤的,直到你有百分百的把握確定箱子裡的球球,猜測的次數越少,tongtong能夠得到的禮物就更好。為了讓tongtong過乙個開開心心的六一,請你找出一種最優的策略,盡可能少的向店主提出猜測來確定球的顏色,輸出猜測次數的期望值。

策略「最優」是指:猜測次數的期望最小。當你有百分百的把握確定箱子裡的球球顏色種類時,則不需要繼續猜測。例如,如果有兩種顏色的球球,箱子裡放的是第二種顏色的球球,你可以猜測「是第一種顏色的球球」。商家會告訴你「錯誤」,所以你可以推測「箱子裡的球球是第二種顏色的」,並且有百分百的把握,所以你就可以結束猜測而不需要額外的一次猜測。這種詢問方式猜測次數為一次(不管你這一次有沒有猜對)。

輸入第一行輸入乙個n,表示有n種顏色的球。 n<=2 000

第二行輸入n個非負小數a1~an,表示是第i種顏色球球的概率,保證加和起來為1。

輸出輸出最小期望,保留7位小數。

複製樣例資料

3

0.5000000000 0.2500000000 0.2500000000

樣例輸出

1.5000000
提示

最佳策略下:第一次詢問「是不是第二種顏色的球球或第三種顏色的球球中的一種」,如果回答「否」則可以知道是第一種顏色的球球,結束詢問;如果回答是「是」則詢問第二次「是不是第二種顏色的球球」。

題解:因為任意一次詢問和回答,都可以確定其中一半的球球集合包含目標球,另一半則不包含目標球。然後再對包含目標球的球球集合進一步劃分,直到包含目標球的集合裡只包含乙個球,就可以百分百確定了。這樣就得到了乙個決策樹(二叉形狀),二叉決策樹根節點到每個葉子的路到都是期中一種情況的解決方案,顯然深度就是詢問次數。       則有:期望=∑(詢問次數*每種情況出現的概率)=∑(葉子對應的深度*它出現在盒子裡的概率)。        而我們知道:這個公式   ∑(深度*元素出現的概率 )    與某種編碼方案的編碼長度期望公式 相同。詢問次數的期望最小也就是編碼長度的期望最小。而解決這個問題的經典方法就是——哈夫曼樹.

上面是題解的解釋,本來想著建樹來著,發現其實沒必要,每個點的層數就是這個數被操作的次數,操作的時候直接加起來即可,要注意的一點就是概率為0的點,直接捨棄。

#includeusing namespace std;

const int n = 2010;

struct node

bool operator < (const node &b)const

};vectorv[n];

int n;

int main ()

node t1, t2;

double ans = 0;

while(q.size() > 1)

printf("%.7f\n", ans);

return 0;

}

哈夫曼樹 猜球球

題目描述 六一到了,為了慶祝這個節日,好多商家都推出了很多好玩的小遊戲。tongtong看到了乙個猜球球的遊戲,有n種除了顏色之外完全相同的球,商家從中拿出來乙個球球放到了箱子裡,已知第i種顏色的球出現在箱子裡的概率為ai。tongtong可以用下面這種方法來確定箱子中球的顏色 向商家提出猜測 是第...

魔術球問題

列舉放的球,先假設新建柱子,拆成兩個點,第乙個點連s,表示後面還可以放 第二個連t表示放到其他柱子上 再列舉放過的數和它是否組成完全平方數,列舉的數的第乙個點向它的第二個點連邊,表示這個球可以放到其他球上,容量都為一 每次跑最大流出來的表示會消掉的柱子個數,如果此時球 消去的比n大則break輸出答...

魔術球問題

題目描述 題解 個人認為網路流二十三題中比較有意思的一道。先列舉球數。每加乙個球,從 s 向 xi 連一條容量為 1 的邊,從 yi 向 t 連一條容量為 1 的邊。然後從 xi 向滿足 i j 為完全平方數的 yj 連容量為 1 的邊。在殘餘網路上跑 ek 或 dinic 如果得到的最大流為 0 ...