csuoj2105Front Nine 概率期望dp

思路分析:用个二维数组记录每个点右边所包含面积的期望值,然后从后往前一个个递推即可。另一个方法是从前往后计算出到达每个点的概率,然后按期望的定义将前一个和后一个点概率的乘积再乘上这两点间的面积即可。

代码:

   从后往前递推期望

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
double dp[100010][110];    //这里dp数组记录从后往前点包含面积的期望
int main(){
    int i,j,n,h,a,p1,p2,p3;
    while(cin>>n>>h>>a>>p1>>p2>>p3){
        double c1,c2,c3;
        c1=p1*0.01;
        c2=p2*0.01;
        c3=p3*0.01;
        memset(dp,0,sizeof(dp));
        for(i=n;i>=1;i--){
            for(j=h;j>=0;j--){
                int x=j+1;
                if(x>h) x=h;
                dp[i][j]+=(dp[i+1][x]+(j+x)/2.0)*c3;
                x=j;
                dp[i][j]+=(dp[i+1][x]+(j+x)/2.0)*c2;
                x=j-1;
                if(x<0) x=0;
                dp[i][j]+=(dp[i+1][x]+(j+x)/2.0)*c1;
            }
        }
        printf("%.10f\n",dp[1][a]);
    }
    return 0;
}

从前往后计算概率

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
double dp[100010][110];  //这里dp数组记录的是到达每个点的概率
int main(){
    int n,x,h,i,j,a,b,c;
    double p1,p2,p3;
    while(scanf("%d%d%d%d%d%d",&n,&h,&x,&a,&b,&c)!=EOF){
        p1=a*0.01;
        p2=b*0.01;
        p3=c*0.01;
        memset(dp,0,sizeof(dp));
        dp[1][x]=1;
        double sum=0;
        for(i=1;i<=n;i++){
            for(j=0;j<=h;j++){
                    if(dp[i][j]!=0){
                         a=j-1;          //上中下三种情况,计算下一个点,同时计算面积期望
                         if(a<0) a=0;
                         dp[i+1][a]+=dp[i][j]*p1;
                         sum+=dp[i][j]*p1*(j+a)/2;
                         a=j;
                         dp[i+1][a]+=dp[i][j]*p2;
                         sum+=dp[i][j]*p2*(j+a)/2;
                         a=j+1;
                         if(a>h) a=h;
                         dp[i+1][a]+=dp[i][j]*p3;
                         sum+=dp[i][j]*p3*(j+a)/2;
                    }
            }
        }
        printf("%.10f\n",sum);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值