题意:去银行取最多K钱,想要全部取完,但是有个限制就是如果你输入取钱的额度超过了你已有的钱,那么会接受一次警告并无法取钱,然后求最多不超过w次警告的前提下你取完所有钱所需要的最少次数。
思路:概率DP,然后dp[i][j]代表还有j次取完不超过i钱所需要的次数期望。那么对于每一个操作都有可能失败或者成功,这是右对应的长度来决定的,但是失败的话就要加一次,这是概率DP从后往前推的一个经验然后注意0也是有可能的。所以0也应该算是区间之内的一个概率。
#include <bits/stdc++.h> using namespace std; const double INF = 1e12; const int MAXN = 2e3+5; const double eps = 1e-7; double dp[MAXN][20]; double Solve(int k, int w) { if(k == 0) return dp[k][w] = 0; if(w == 0) return INF; if(dp[k][w] > eps) return dp[k][w]; dp[k][w] = INF; for(int i=1; i<=k; i++) dp[k][w] = min(dp[k][w],(double)(k-i+1)/(k+1)*Solve(k-i,w)+(double)i/(k+1)*Solve(i-1,w-1)+1); return dp[k][w]; } int main() { int k, w; while(~scanf("%d%d",&k,&w)) { w = min(w,12); printf("%.6lf ",Solve(k,w)); } return 0; }