ZOJ 3640 Help Me Escape(概率dp)

来源:互联网 发布:只有我知 在线观看 编辑:程序博客网 时间:2024/05/22 02:17

题目链接:ZOJ 3640 Help Me Escape

概率dp。

开始没看明白题意,以为增加战斗力后还在这条path,后来发现不是这样的,而是增加战斗力后再随机选择path。

记忆化搜索很好想,递推的话开始没想明白从什么值开始往f循环,后来看了看别人写的代码自己又推了推才恍然大悟。

#include <iostream>#include <cstdio>#include <cstring>#include <cmath>using namespace std;const int MAX_N = 100 + 10;const int MAX_M = 10000/* + 10000*/ + 10000 +500;const double e = 1e-9;double dp[MAX_M];int c[MAX_N];int n, f;int get_t(int ci){    double ans = (1.0 + sqrt(5)) / 2.0 * ci * ci;    return (int)ans;}int main(){    while(scanf("%d%d", &n, &f) != EOF)    {        int _max = 0;        for(int i = 1; i <= n; i++)        {            scanf("%d", &c[i]);            _max = max(_max, c[i]);        }        _max = max(_max << 1, f);        // _max = (_max << 1) + f;//左移操作符的优先级比较低        for(int i = _max; i >= f; i--)        {            dp[i] = 0;            for(int j = 1; j <= n; j++)            {                if(i > c[j])                    dp[i] += (1.0 / n) * get_t(c[j]);                else                    dp[i] += (1.0 / n) * (dp[i + c[j]] + 1);            }        }        printf("%.3lf\n", dp[f]);    }    return 0;}
#include <iostream>#include <cstdio>#include <cstring>#include <cmath>using namespace std;const int MAX_N = 100 + 10;const int MAX_M = 10000 + 10000 + 500;const double e = 1e-9;double dp[MAX_M];int c[MAX_N];int n, f;int get_t(int ci){    double ans = (1.0 + sqrt(5)) / 2.0 * ci * ci;    return (int)ans;}double solve(int f){    if(fabs(dp[f] + 1) > e)        return dp[f];    dp[f] = 0.0;    for(int i = 1; i <= n; i++)    {        if(f > c[i])            dp[f] += (1.0 / n) * get_t(c[i]);        else            dp[f] += (1.0 / n) * (solve(f + c[i]) + 1);    }    return dp[f];}int main(){    while(scanf("%d%d", &n, &f) != EOF)    {        for(int i = 1; i <= n; i++)            scanf("%d", &c[i]);        memset(dp, -1, sizeof(dp));        printf("%.3lf\n", solve(f));    }    return 0;}


0 0