1、感谢Staginner详细的解题报告!否则我一定还在摸爬滚打。
2、这道题给出要求答的题目数量,以及概率p的下限t(最高为1),要求计算获得奖金的期望。
3、刚开始没注意p在【t,1】上均匀分布,以为答对的概率就是t,所以怎么也理解不了样例数据,后来才知道要利用连续型随机变量的期望公式来计算出p的“估计值”。(p相当于一个随机变量,无论是利用《概率论与数理统计》课本上的公式来积分,还是自己脑子里想一想,都能知道p的期望是(1+t)/2,当然,还没完。)
4、注意了,题目还说“plays the best strategy”,什么意思呢?就是做出对自己最有利的选择。每次在答题前,都要选择放弃,拿走奖金,或者冒险答题。如果冒险答题的收益不如放弃,那么选择放弃,否则冒险。中间肯定有一个临界点m,当概率p大于m的时候,p*冒险答题的收益(不一定就是2倍!因为下一次的决策中也可能选择放弃,所以说收益应该是一个期望值)>放弃所得收益,那么选择冒险,否则选择放弃。
5、这个临界点m=f[num]/d[num+1],其中f是放弃后所得收益(即2的num次方),d是坚持后所得收益(不一定是2的num+1次方),下标num的意思是做决策时已经答对的题数。
6、需要分类讨论,如果这个m在t的左边,那么无论如何都会选择冒险,因为这样比较有利,如果m在t与1之间,那么要根据m分类讨论,m左边那部分意味着选择放弃,右边那部分意味着选择冒险。注意在右边的时候,p的期望为(1+m)/2。
7、一个递归程序就可以解决本题,注意dfs(0)的意思是已经答了0道的时候,估计一下能获得的收益是多少,dfs(n)当然是2的n次方啦,都答对n道了,那么肯定获得最高奖金——2的n次方无疑了。
8、一次AC~具体见以下程序。
#include<cstdio>
using namespace std;
int n,f[35];
double t,d[35];
double dfs(int num){
if(num==n) return d[n]=f[n];
double temp=dfs(num+1);
double m=f[num]/temp;
if(m<t) d[num]=(t+1)/2*temp;
else d[num]=(m-t)/(1-t)*f[num]+(1-m)/(1-t)*(m+1)/2*temp;
return d[num];
}
int main(){
f[0]=1;
for(int i=1;i<=31;i++)
f[i]=f[i-1]*2;
while(scanf("%d%lf",&n,&t)==2){
if(n==0) break;
dfs(0);
printf("%.3lf\n",d[0]);
}
return 0;
}