zoukankan      html  css  js  c++  java
  • HDU 5781 ATM Mechine

    题目大意:某个未知整数x等概率的分布在[0,k]中。每次你都可以从这个整数中减去一个任意整数y,如果x>=y,那么x=x-y,操作次数累计加1;否则,将会受到一次错误提示。当错误提示超过w次,将会对你的人生产生影响。现在,你的任务是将x逐步变为0,求最少操作次数的期望值。

    题目分析:概率DP求期望。定义状态dp(k,w)表示整数分布在[0,k],错误提示次数上限为w时的最少操作次数的期望。

    则dp(k,w)=min(p1*dp(k-y,w)+p2*(y-1,w-1))+1,其中p1、p2分别为k>=y、k<y的概率,p1=(k-y+1)/(k+1)、p2=y/(k+1)。因为你非常聪明,所以你每次都会二分的选择要减掉的整数y。根据题目的数据规模,你最多会操作log2(k)+1次,所以你被错误提示的次数最多log2(k)次。这样,便大大减少了状态数目,使得上述方程能够得以实现。

    输入:

    1 1
    4 2
    20 3

    输出:

    1.000000
    2.400000
    4.523810

    参考代码:

    #include <iostream>

    #include <cstdio>

    #include <cstring>

    #include <algorithm>

    using namespace std;

    #define maxn 2010

    #define LL long long

    double dp[maxn][maxn];

    #define inf 0x3f3f3f3f

    double getdp(int i,int j)

    {

        if(i==0)

            return dp[i][0]=0;

        if(j==0)

            return dp[i][j]=inf;

        if(dp[i][j]!=-1.0)

            return dp[i][j];

        double ans=inf;

        for(int k=1;k<=i;k++)

        {

            ans=min(ans,(i+1-k)/(i+1.0)*getdp(i-k,j)+k/(i+1.0)*getdp(k-1,j-1)+1);

        }

        return dp[i][j]=ans;

    }

    int main()

    {

        int k,w;

        for(int i=0;i<maxn;i++)

            for(int j=0;j<maxn;j++)

                dp[i][j]=-1.0;

        while(~scanf("%d%d",&k,&w))

        {

            printf("%.6f ",getdp(k,min(w,15)));

        }

    }

  • 相关阅读:
    六、显式锁和AQS
    五、原子操作(CAS)
    四、线程的并发工具类
    BZOJ 2176 Strange string ——最小表示法
    BZOJ 2882 工艺 ——后缀自动机 最小表示法
    Codeforces Round #401 (Div. 2)
    BZOJ 2331 [SCOI2011]地板 ——插头DP
    BZOJ 2005 [Noi2010]能量采集 ——Dirichlet积
    BZOJ 1087 [SCOI2005]互不侵犯King ——状压DP
    BZOJ 1072 [SCOI2007]排列perm ——状压DP
  • 原文地址:https://www.cnblogs.com/137033036-wjl/p/5745835.html
Copyright © 2011-2022 走看看