HDU 5236 Article(概率DP)

 http://acm.hdu.edu.cn/showproblem.php?pid=5236

题意:
现在有人要在文本编辑器中输入n个字符,然而这个编辑器有点问题。

在i+0.1s(i>=0)的时刻可以输入一个字符。

在i+0.9s(i>0)的时刻系统可能会崩溃,需要重新开始或者从上次保存点开始。

在i时刻可以选择保存,保存需要按x个键(假设按键速度极快)。最后完成时必须保存一下。

现在要你来确定一个最佳的输入策略,使得最后按键的期望值最小。

思路:
首先不考虑保存的情况:

则输入第i个字符的期望值为:$dp[i] = dp[i-1] + p*(1+dp[i]) + (1-p)$。化简后得:$dp[i]=(dp[i-1]+1)/(1-p)$。

接下来考虑保存的情况,可以猜想尽量的把保存点安排的均匀一些,即每输入k或k+1个字符就保存一次。那么可以枚举保存的次数,取最小值。

 1 #include<iostream>
 2 #include<cstdio>
 3 using namespace std;
 4 const int maxn = 1e5+5;
 5 
 6 int n, x;
 7 double p;
 8 double dp[maxn];
 9 
10 int main()
11 {
12     //freopen("in.txt","r",stdin);
13     int T;
14     int cas = 0;
15     scanf("%d",&T);
16     while(T--)
17     {
18         scanf("%d%lf%d",&n,&p,&x);
19         for(int i=1;i<=n;i++)
20             dp[i] = (dp[i-1]+1)/(1-p);
21         double ans = 0x3f3f3f3f;
22         for(int i=1;i<=n;i++)
23         {
24             int k = n/i;
25             int r = n%i;
26             ans = min(ans, r*dp[k+1] + (i-r)*dp[k] + i*x);
27             //将剩余的r个字符分配到r块中,那么这r块需要敲k+1个字符
28             //剩余的i-r块则只需要敲k个字符
29         }
30          printf("Case #%d: %.6f
", ++cas, ans);
31     }
32     return 0;
33 }
原文地址:https://www.cnblogs.com/zyb993963526/p/9258932.html