ZOJ 3640 Help Me Escape 概率DP 记忆化DFS

来源:互联网 发布:给游戏做美工需要什么 编辑:程序博客网 时间:2024/05/16 16:06

题目大意:

就是现在初始状态有f点战斗力, 每天都会等可能地被送到某条路的入口处, 如果f > c[i]那么久花费t[i] = c[i]*c[i]*(1 + sqrt(5))/2 向下取整的时间才能出去, 否则 f 上升c[i]花费当天的时间, 第二天继续随机传送...直到出去为止, 问出去需要的时间的期望


大致思路:

很基本的一个dfs类型的概率dp, dfs(double f)表示当战斗力为 f 的时候需要的天数期望, 普通地dfs即可, 注意记忆化, 不然会超时

具体细节见代码


代码如下:

Result  : Accepted     Memory  :  428 KB     Time  :  620 ms

/* * Author: Gatevin * Created Time:  2014/12/22 21:40:05 * File Name: Sora_Kasugano.cpp */#include<iostream>#include<sstream>#include<fstream>#include<vector>#include<list>#include<deque>#include<queue>#include<stack>#include<map>#include<set>#include<bitset>#include<algorithm>#include<cstdio>#include<cstdlib>#include<cstring>#include<cctype>#include<cmath>#include<ctime>#include<iomanip>using namespace std;const double eps(1e-8);typedef long long lint;int c[110];int t[110];double vis[20010];int n, f;double dfs(int f){    if(vis[f] > 0) return vis[f];    double ret = 0;    for(int i = 1; i <= n; i++)        if(c[i] < f)            ret += t[i]*1.0/n;        else            ret += (dfs(f + c[i]) + 1)/n;    vis[f] = ret;    return ret;}int main(){    while(~scanf("%d %d", &n, &f))    {        for(int i = 1; i <= n; i++)        {            scanf("%d", c + i);            t[i] = floor(c[i]*(1 + sqrt(5.0))/2*c[i]);        }        for(int i = f; i <= 20000; i++) vis[i] = -1;//初始化标记, f前面的不用初始化        double ans = dfs(f*1.0);        printf("%.3f\n", ans);    }    return 0;}


0 0