Article
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 917 Accepted Submission(s): 328
Problem Description
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 writen 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 i−0.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.
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
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 integern≤105 ,
a positive real 0.1≤p≤0.9 ,
and a positive integer x≤100 .
Next T lines: each line has a positive integer
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 than10−6 .
Your answer is considered correct if and only if the absolute error or the relative error is smaller than
Sample Input
2 1 0.5 2 2 0.4 2
Sample Output
Case #1: 4.000000 Case #2: 6.444444
Source
Recommend
题意
要求输入一篇N个字符的文章,对所有非负整数i:
每到第i+0.1秒时可以输入一个文章字符
每到第i+0.9秒时有P的概率崩溃(回到开头或者上一个存盘点)
每到第i秒有一次机会可以选择按下X个键存盘,或者不存
打印完整篇文章之后必须存盘一次才算完成
输入多组N,P,X选择最佳策略使得输入完整篇文章时候按键的期望最小,输出此期望
题解:
首先我们先分析不考虑保存的情况的dp
dp[i]=dp[i-1]+p*(1+dp[i])+(1-p);
敲出i个字符, 首先得敲出i-1个字符, 所以有第一部分的dp[i-1]; 然后敲下一个字符时, 有两种可能, p概率会丢失, (1-p)概率不会丢失, 对于丢失的情况就还得重新敲dp[i]次了(期望次数), 不丢失的情况就只有一次就成功了, 所以是(1-p) * 1。
所以化简为: dp[i] = (dp[i-1] + 1) / ( 1- p)
然后再考虑存盘的情况,我们枚举存了xx次盘,也就是把这nn个字符分为xx段,每打完一段就存一次盘。由于,可以看出d(n)是指数型增长的,所以就尽可能均匀地把n个字符分成xx段。或者也可以求一下d(n)的通项公式为:来验证。其实最后的贪心还是有点懵,不过好像算是合理,有时间问问老L
#include <bits/stdc++.h> #define INF 1e9 using namespace std; const int MAXN=1e5+7; int n,x; double p; double dp[MAXN]; int main() { int t; scanf("%d",&t); for(int tt=1; tt<=t; ++tt) { scanf("%d%lf%d",&n,&p,&x); dp[0]=0.0; for(int i=1; i<=n; ++i) dp[i]=(dp[i-1]+1)/(1-p);///求出敲i个字符的期望 double ans=INF; for(int i=1; i<=n; ++i) ///保存的次数 { int a=n/i; int b=n%i; ans=min(ans,dp[a+1]*b + dp[a]*(i-b) + x*i); } printf("Case #%d: %.6f ",tt,ans); } return 0; }