博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HDU 5781 ATM Mechine
阅读量:6860 次
发布时间:2019-06-26

本文共 1097 字,大约阅读时间需要 3 分钟。

题目大意:某个未知整数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 14 220 3

输出:

1.0000002.4000004.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\n",getdp(k,min(w,15)));

    }

}

转载于:https://www.cnblogs.com/137033036-wjl/p/5745835.html

你可能感兴趣的文章
使用index+Match函数组合实现反向、双向等复杂的表格查找
查看>>
数据库与数据仓库的区别
查看>>
BZOJ 3998 [TJOI2015]弦论
查看>>
【C语言】19-static和extern关键字1-对函数的作用
查看>>
MapReduce Input Split(输入分/切片)详解
查看>>
Java Arrays.asList注意事项
查看>>
LeetCode 359 Logger Rate Limiter
查看>>
Windows核心编程04-字符编码
查看>>
mysqlcluster笔记
查看>>
ArcCore重构-Makefile模块化
查看>>
例10-3 uva10375(唯一分解定理)
查看>>
Python 魔术方法指南
查看>>
HTML概述
查看>>
BZOJ 4245: [ONTAK2015]OR-XOR
查看>>
github 错误
查看>>
idea 项目转 eclipse项目
查看>>
js去除空格,判断是否包含
查看>>
css3 背景色 实现边框渐变运动动画
查看>>
c#实现常用排序算法
查看>>
rails中输出excel
查看>>