• 博客园logo
  • 会员
  • 周边
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
james1207

博客园    首页    新随笔    联系   管理    订阅  订阅

HDU 4089 Activation

        概率dp,这种一个点作为起点,求到多点的概率或期望的都可以倒过来想。。。即让起点变为那多个点,终点(即答案)即为原来起点的值。

       dp[ i ][ 1 ] = p1 * dp[ i ][ 1 ] + p2 * dp[ i ][ i ] ---- (1);

       dp[ i ][ j ]  = p1 * dp[ i ][ i ]  + p2 * dp[ i ][ j - 1] + p3 * dp[ i - 1][ j - 1]  + (j <= k ? p4 : 0) ----- (2);   

       对(2)式递推下去,就可以结合(1)式得出dp[ i ][ 1]的值。。。然后递推即可,然后求得的dp[ n ][ m ] 即为所求。

       注意:p3 && p4 == 0 时要特判。。。

 

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define LL long long
#define CLR(a, b) memset(a, b, sizeof(a))

using namespace std;
const int N = 2002;
const int MOD = 1e9 +7;

double dp[2][N];

int main()
{
    int n, m , k, i, j;
    double p1, p2, p3, p4;
    while(scanf("%d%d%d%lf%lf%lf%lf", &n, &m, &k, &p1, &p2, &p3, &p4) != EOF)
    {
        if(p4 == 0) {puts("0.00000"); continue;}
        dp[1][1] = p4 / (1 - p1 - p2);
        double a = p2 / (1 - p1), b = p3 / (1 - p1), c = p4 / (1 - p1), tmp, d;
        for(i = 2; i <= n; i ++)
        {
            tmp = 0;d = a;
            for(j = 2; j <= i; j ++)
            {
                tmp = tmp * a + dp[1 - (i & 1)][j - 1] * b + (j <= k ? c : 0.0) ;
                d *= a;
            }
            tmp = tmp * a + c;
            dp[i & 1][1] = tmp / (1 - d);
            for(j = 2; j <= i; j ++)
            {
                dp[i & 1][j] = dp[1 - (i & 1)][j - 1] * b + dp[i & 1][j - 1] * a + (j <= k ? c : 0.0);
            }
        }
        printf("%.5f\n", dp[n & 1][m]);
    }
}


 


 

posted @ 2013-09-17 23:25  Class Xman  阅读(135)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3