HDU5236 Article(期望dp)

Article

传送门1
传送门2
As the term is going to end, DRD begins to write his final article.

DRD uses the famous Macrohard’s software, World, to write his article. Unfortunately this software is rather unstable, and it always crashes. DRD needs to write n characters in his article. He can press a key to input a character at time i+0.1, where i is an integer equal or greater than 0. But at every time i0.1 for integer i strictly greater than 0, World might crash with probability p and DRD loses his work, so he maybe has to restart from his latest saved article. To prevent write it again and again, DRD can press Ctrl-S to save his document at time i . Due to the strange keyboard DRD uses, to press Ctrl-S he needs to press x characters. If DRD has input his total article, he has to press Ctrl-S to save the document.

Since World crashes too often, now he is asking his friend ATM for the optimal strategy to input his article. A strategy is measured by its expectation keys DRD needs to press.

Note that DRD can press a key at fast enough speed.

Input

First line: an positive integer 0T20 indicating the number of cases.
Next T lines: each line has a positive integer n105 , a positive real 0.1p0.9 , and a positive integer x100 .

Output

For each test case: output ”Case #k: ans” (without quotes), where k is the number of the test cases, and ans is the expectation of keys of the optimal strategy.
Your answer is considered correct if and only if the absolute error or the relative error is smaller than 106.

Sample Input

2
1 0.5 2
2 0.4 2

Sample Output

Case #1: 4.000000
Case #2: 6.444444


题意

你现在要打n个字符,但是程序随时可能会崩溃。
你可以在恰当的时机按下 Ctrl−S键,崩溃后,会从最后一次保存的情况继续开始打字。
1. 在每个第 i0.1s(i>0) 的时候,程序崩溃的概率为p
2. 在每个第 is(i0) 的时候,你可以一口气按下x个键来存盘
3. 在每个第 i+0.1s(i0) 的时候,你可以按下一个键来打字
求采取最优策略下,打完这 n 个字符,并且最后存盘,总按键次数的期望。

分析

定义dp[i]表示敲出i个字符时按键期望。
因为敲第 i 个字符首先得敲出i1个字符,然后敲下一个字符时, 有两种可能, p 概率会丢失,(1p)概率不会丢失, 对于丢失的情况就还得重新敲 dp[i] 次, 不丢失的情况就只有一次就成功, 所以是 (1p)1 。于是得到

dp[i]=dp[i1]+p(1+dp[i])+(1p),

然后进行类似解方程的操作得到
dp[i]=(dp[i1]+1)1p.

另外,我们可以发现dp数组是指数增长的,而且 11p>1 ,所以随着 i 的增大, dp[i]增大的越快。我们可以枚举保存的次数k, 保存k次就相当于把n个字符分成k部分来完成, 由上面结论可知, 这k部分尽量均匀。

CODE
#include<cstdio>
#define N 100005
typedef double db;
int n,x;
db p,dp[N];
inline void Min(db &x,db y) {if(x>y)x=y;}

int main() {
    int t;
    scanf("%d",&t);
    for(int cas=1; cas<=t; cas++) {
        scanf("%d%lf%d",&n,&p,&x);
        for(int i=1; i<=n; i++)dp[i]=(dp[i-1]+1)/(1-p);
        db ans=dp[n]+x;
        for(int i=2; i<=n; i++)Min(ans,dp[n/i+1]*(n%i)+dp[n/i]*(i-n%i)+i*x);
        printf("Case #%d: %.6f\n",cas,ans);
    }
    return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值