描述
遊戲者開始是$1的獎金,要求回答n個問題。對每個問題,可以:
1)、退出並保有獎金
2)、回答問題。
如果錯誤,就退出並什麼都得不到。如果正確,那麼獎金翻倍,並可繼續回答下一個問題。
在回答最後一個問題後,他獲得獎金並退出。遊戲者想要最大化他期望獲得的獎金。
一旦提出了一個問題,遊戲者就能以機率p正確回答。對每個問題,假設p是一個隨機變數,分布的範圍是t<=p<=1。
輸入
輸入M行數,每一行有兩個數字:整數n和實數t, 1 ≤ n ≤ 30, 0 ≤ t ≤ 1。n表示要回答的問題的個數,t表示遊戲者能正確回答問題的機率的下限。以兩個0表示輸入結束。
輸出
對每個輸入n,t,輸出遊戲者採用最佳策略時所期望獲得的獎金,保留三位小數。
範例輸入
1 0.5
1 0.3
2 0.6
0 0
範例輸出
1.500
1.357
2.560
這個題目從一開始思路上就有問題,後來結合別人的解題報告來看,終於明白是怎麼回事了,而且也突然發現,貌似我適合冒險但不適合賭博……
我們不妨設a[i]表示正確做完第i道題的收益的期望,顯然我們最後要求的就是a[0]咯,但這個先放一放,我們先討論一下在做第i+1個題目前我們是選擇答題呢還是選擇放棄呢。
首先,我們可以直觀的想到,如果做完i題就退出的話,就可以得到2^i這麼多錢。不妨假設答對第i+1個題的機率為p,那麼我們自然會想到用p乘以“某個值”表示答題所獲得的收益的期望,如果p乘以這個值大於2^i的話,我們肯定會選擇答題咯,因為若是這樣答題的話收益的期望是大於不答題的。那麼現在問題就來了,這個“某個值”是什麼呢?可能的最大值?可能的最小值?還是平均值(或者說是期望)?
如果做個比喻的話,選最大值的就是冒險狂,選最小值的就是膽小鬼,選平均值的就是接受過良好高等教育的ACMer,一開始我就成了冒險狂……
後來想想,也確實只有平均值在統計裡面才比較有說服力,因此題目中所謂的plays the best strategy就是按我們上面所說的去決策每次究竟是答題還是不答題。上面我們只是對於p是固定值來討論的,如果我們對p是任意的去討論的話,顯然不答題的平均收益是不變的,因為它和p沒關係,仍是2^i,如果答題的話平均收益就應該是(ep+1)/2*a[i+1],ep就是我們前面討論的“分水嶺”,用運算式寫出來就是ep=2^i/a[i+1],當p>ep,那麼p*a[i+1]>2^i,也就是說如果答對這個題我就可以獲得a[i+1]這麼多錢,再乘答對的機率p就是答第i+1題的收益的期望,如果這個期望大於2^i,那麼就會選擇答題。當然題目中讓算的是總收益,我們再各自乘以答題與否這些情況出現的機率即可,即a[i]=(ep-t)/(1-t)*2^i+(t-ep)/(1-t)*(ep+1)/2*a[i+1],這個式子值列出了ep>t的情況,對於ep<=t的情況,也可以類似寫出運算式。
現在我們就發現了,計算a[i]是需要用到a[i+1]的,那我們怎麼辦?倒著算唄。那麼a[N]是多少?顯然是2^N,因為答對第N個題之後收益的期望自然就是最大的收益。
#include<stdio.h>#include<string.h>#include<math.h>#define MX 35int N;double T, q[MX];int main(){ q[0] = 1; for(int i = 1; i <= 30; i ++) q[i] = 2 * q[i - 1]; while(1) { scanf("%d%lf", &N, &T); if(!N) break; if(fabs(1 - T) < 1e-9) printf("%.3lf\n", q[N]); else { int i, j, k; double eq, f = 1, quit; f = q[N]; for(i = N - 1; i >= 0; i --) { quit = q[i]; eq = quit / f; if(eq <= T) f = (T + 1) / 2 * f; else f = (eq - T) / (1 - T) * quit + (1 - eq) / (1 - T) * (eq + 1) / 2 * f; } printf("%.3lf\n", f); } } return 0;}