题意:账户中有[0,k]的钱,每次可以取Y的钱,如果所要取得钱Y大于账户中的钱警告一次,警告次数不能超过M次,问把全部钱取出来的期望是次数是多少?
题解:dp[K][W] = min(dp[K][W],dp[K-i][W]*(K-i+1)/(K+1)+dp[i-1][W-1]*i/(K+1)+1);dp[i][j]表示中户中的钱[0,i],有j次错误机会的期望。答案就是dp[ K][W]。如果Alice选用二分法,那么取钱的次数就是log2(K),所以当W大于log2(K)的时候是只要考虑w等于log2(K)。
#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<string.h>
using namespace std;
#define N 2100
double dp[N][16];
double dfs(int K,int W){
if(dp[K][W]>-1){
return dp[K][W];
}
if(K==0) return 0;
if(W==0) return 1e10;
dp[K][W]=1e10;
for(int i=1;i<=K;i++){
dp[K][W] = min(dp[K][W],dfs(K-i,W)*(K-i+1)/(K+1)+dfs(i-1,W-1)*i/(K+1)+1);
}
return dp[K][W];
}
int main(){
int K,W;
for(int i=0;i<=N;i++){
for(int j=0;j<16;j++){
dp[i][j]=-2;
}
}
while(scanf(" %d %d",&K,&W)==2){
if(W>14) W = 12;
printf("%.6lf\n",dfs(K,W));
}
return 0;
}