您的位置:首页 > 其它

沈阳集训day6 机房模拟赛 t1自动取款机 题解

2017-06-06 19:32 267 查看

自动取款机(256M,1s)

【问题描述】

小沈阳在小品里说过:“人生最痛苦的事情是人死了,钱还没花了”。 于是小宋(80 岁)决定要将所有的储蓄从 ATM 机中取出花光。 小宋忘记了她有多少存款 (银行卡密码她是记得的 2333),这个奇怪的 ATM 不支持查询存款余额功能。小宋知道她 存款的唯一信息是存款上限是 K 元,这意味着小宋的存款 x 是 0 到 K 之间的随机整数(包 括 K)。 每次小宋都可以尝试从 ATM 中拿出一些钱。 如果她要取的 y 元钱不大于她的存款, ATM 将立即给小宋 y 元。 但如果她的存款小于 y,小宋将收到 ATM 的警告。 如果小宋被警告超过 w 次,那么她将被警方带走,作为小偷。 小宋希望取钱次数期望最小。 由于小宋聪明,她总是采取最好的策略。 请计算小宋将所有储蓄从自动取款机中取出期望次数最小值是多少,并不得被警方带走。

【输入格式】

每个测试点包含多组测试数据(最多 10 组) 每组测试数据包含两个整数 K,和 W 1≤K,W≤2000

【输出格式】

对于每组测试数据输出取钱次数最小的期望值,舍入到小数点后 6 位。

【样例输入】

11

42

203

【样例输出】

1.000000

2.400000

4.523810

然而她并不知道赵本山说了:“人生最最痛苦的事情是人活着呢钱没了” 这是个悲伤的故事。

显然,这是一道比较入门的期望dp,基本没有任何难度(只是在嘲讽自己做不出来),我们可以这样考虑

取完不单单是指他存折里没钱了,小宋需要得到确定的信息告诉他取完了。

譬如小宋知道存折里最多1元,取一次就取完了。

或者当取1元的时候被警告了,也表示他存折里没钱了。

考虑dp[i][j]表示当前小宋直到存折里钱数上限为i,还可被警告j次,取完钱的期望。





注意到题目中有一句话非常地关键,那就是小宋非常聪明,每次总是采取最优的猜钱方式,所以如果用二分这种方法比较聪明的话,小宋一定会采取这种或者比这种方法更优的方法,所以呢,最多猜log2000次,所以直接优化即可

w=min(w,log2000)

代码如下

#include<cstdio>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
double dp[2010][16];
double dfs(int w,int c){
if(dp[w][c]!=-1) return dp[w][c];
if(w==0) return 0;
if(c==0) return 1e9;
double ans=1e9;
double k=1.0/(1.0+w);
for(int i=1;i<=w;i++)
ans=min(ans,i*k*dfs(i-1,c-1)+(w+1-i)*k*dfs(w-i,c)+1);
return dp[w][c]=ans;
}
int main(){
int k,w;
for(register int i=0;i<=2010;i++){
for(register int j=0;j<=16;j++){
dp[i][j]=-1;
}
}
while(scanf("%d%d",&k,&w)!=EOF){
w=min(w,15);
printf("%0.6lf\n",dfs(k,w));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: