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
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 0≤T≤20 indicating the number of cases.
Next T lines: each line has a positive integer n≤105 , a positive real 0.1≤p≤0.9 , and a positive integer x≤100 .
Output
For each test case: output ”Case #k: ans” (without quotes), where k is the number of the test cases, and
Your answer is considered correct if and only if the absolute error or the relative error is smaller than 10−6.
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. 在每个第 i−0.1s(i>0) 的时候,程序崩溃的概率为p
2. 在每个第 is(i≥0) 的时候,你可以一口气按下x个键来存盘
3. 在每个第 i+0.1s(i≥0) 的时候,你可以按下一个键来打字
求采取最优策略下,打完这 n 个字符,并且最后存盘,总按键次数的期望。
分析
定义
因为敲第 i 个字符首先得敲出
然后进行类似解方程的操作得到
另外,我们可以发现dp数组是指数增长的,而且 11−p>1 ,所以随着 i 的增大,
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;
}