您的位置:首页 > 其它

ZOJ 3640 Help Me Escape(概率-期望DP+神坑)

2017-09-06 15:32 381 查看

Background

    If thou doest well, shalt thou not be accepted? and if thou doest not well, sin lieth at the door. And unto thee shall be his desire, and thou shalt rule over him. 

    And Cain talked with Abel his brother: and it came to pass, when they were in the field, that Cain rose up against Abel his brother, and slew him. 

    And the LORD said unto Cain, Where is Abel thy brother? And he said, I know not: Am I my brother's keeper? 

    And he said, What hast thou done? the voice of thy brother's blood crieth unto me from the ground. 

    And now art thou cursed from the earth, which hath opened her mouth to receive thy brother's blood from thy hand; 

    When thou tillest the ground, it shall not henceforth yield unto thee her strength; a fugitive and a vagabond shalt thou be in the earth.

—— Bible Chapter 4
Now Cain is unexpectedly trapped in a cave with N paths. Due to LORD's punishment, all the paths are zigzag and dangerous. The difficulty of the ith path is ci.

Then we define f as the fighting capacity of Cain. Every day, Cain will be sent to one of the N paths randomly.

Suppose Cain is in front of the ith path. He can successfully take ti days to escape from the cave as long as his fighting capacity f is larger than ci. Otherwise, he has to keep trying day after day. However,
if Cain failed to escape, his fighting capacity would increase ci as the result of actual combat. (A kindly reminder: Cain will never died.)

As for ti, we can easily draw a conclusion that ti is closely related to ci. Let's use the following function to describe their relationship:



After D days, Cain finally escapes from the cave. Please output the expectation of D.

Input
The input consists of several cases. In each case, two positive integers N and f (n≤ 100, f ≤ 10000) are given in the first line. The second line includes N positive integers ci (ci ≤ 10000,
1 ≤ i ≤ N)

Output
For each case, you should output the expectation(3 digits after the decimal point).

Sample Input
3 1
1 2 3


Sample Output
6.889


 【题解】

 这道题被坑
4000
的太惨了,哇了不知道多少遍,真想怼死出题人,坑的不要不要的...

 题意大概美化一下,就是有个人在一个山洞里,现在周围有n条路,每条路有一个妖怪,攻击力是c[i],只有打败路上的妖怪才能出去(它的攻击力要大于妖怪的攻击力),所花  费的时间就是题中给出的公式(神坑),如果你走进一条路被打败了,那么就要多花一天时间来养伤,并且你的攻击力在原基础上会增加c[i];

 做法就是设dp[i]表示攻击力为i时逃出去所需要时间的期望值,那么

 if(i>c[j])  dp[i]+=((1+sqrt(5))/2)*c[j]*c[j]/n;

 else dp[i]+= (1+dp[i+c[j]])/n;

 不知道你注意到没有,题中给的式子加了个中括号,坑点出来了,这个中括号表示里面的值要向下取整。。。比如值是6.14,那取整完就是6.00,就是取数轴上左边离它最近的整数。

 反正我是栽在这上面了,怎么算都不对,最最后终于发现问题了。。

 【AC代码】

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<math.h>
using namespace std;
const int N=105;
int f,m;
int p
;
double dp[20010];
double x=(1.0+sqrt(5.0))/2;

int main()
{
while(~scanf("%d%d",&m,&f))
{
int maxn=0;
for(int i=1;i<=m;++i){
scanf("%d",&p[i]);
maxn=max(maxn,p[i]);
}
double ans=0;
for(int i=1;i<=m;++i)//求出打败每只妖怪逃出去的时间期望值
ans+=floor(x*p[i]*p[i])*1.0/m;//floor函数  向下取整
for(int i=maxn+1;i<=maxn*2;++i)//预处理攻击力增加后逃出去的时间期望值
dp[i]=ans;
for(int i=max(maxn,f);i>=f;--i)
{
dp[i]=0;
for(int j=1;j<=m;++j){
if(i>p[j]) dp[i]+=floor(x*p[j]*p[j])*1.0/m;//打得过妖怪
else dp[i]+=(1+dp[i+p[j]])/m;//打不过  判断过一天攻击力增加后是否能打过
}
}
printf("%.3f\n",dp[f]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: