HDU 5781 ATM Mechine 多校赛 概率dp

来源:互联网 发布:linux mtp挂载 编辑:程序博客网 时间:2024/05/17 23:37

点击打开链接

已知ATM机中有最多n元钱,每次可以从ATM机中请求取出任意多的钱,若钱数足够则能成功取出,否则会受到一次警告.如果警告次数超过m次就会被当做小偷抓走.求在保证不能被抓走的前提下,若采取最优策略,期望多少步能够取走所有的钱.

题解

设当前状态dp[i][j],i为最大钱数,j为剩余报错数, 
若i > 0、 j > 0, 
则dp[i][j] = minik=1(ik+1i+1dp[ik][j]+ki+1dp[k1][j1]+1), 

对于k不超过剩余的情况:

dp[i-k][j]:表示i-k钱的时的操作次数的期望;

(i-k+1)/(i+1)  表示 [0,1,......i] 这个区间总共有i+1种拿法  ,(i-k+1) 表示从i块钱中拿走了k块钱 此时区间就变成[0,,....i-k]就只剩下i-k+1种拿法。

(发生的概率)

对于K超过剩余的钱数的情况:

dp[k-1][j-1]  K大于剩余的钱数时,一定要由 k-1 钱的时候推出 ,此时浪费了一次机会。

(k)/(i+1)   表示i+1种拿法,k表示在[0......k-1]的区间中有k中机会。(发生的概率)

前一项为k不超过剩余的情况,后一项为超过,1为当前操作的一步。 
i = 0时为0, j=0时为无穷大。

复杂度O(k2w) 因为k<2000, 若采取二分,最坏步数为log20002, 所以w = min(w, 11), 不会超时。

扩展链接:点击打开链接 鹰蛋acm从《鹰蛋》一题浅析对动态规划算法的优化

#include<bits/stdc++.h>#define LL long longusing namespace std;const int INF = 0x3f3f3f3f;const int MAXN = 2010;double dp[MAXN][20];int main(){     int k, w;    for(int i = 1; i < MAXN; i++)        dp[i][0] = INF;            for(int i = 0; i < 20; i++)        dp[0][i] = 0;            for(int i = 1; i < MAXN; i++)        for(int j = 1; j < 20; j++)        {   double t = INF;            for(int k = 1; k <= i; k++)                t = min(t, (i-k+1.0)/(i+1)*dp[i-k][j]+k/(i+1.0)*dp[k-1][j-1]+1);            dp[i][j] = t;        }    while(~scanf("%d%d", &k, &w))        printf("%.6f\n", dp[k][min(w, 11)]);    return 0;}


1 0
原创粉丝点击