概率dp-hdu-4089-Activation
来源:互联网 发布:手机支持什么网络 编辑:程序博客网 时间:2024/05/16 08:14
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=4089
题目意思:
n个人排队尝试游戏,队首中有四种情况。
1、动作失败重新连,队列不变,概率为p1.
2、服务器链接失败重新连,第一个人排到队尾,概率为p2.
3、连接成功,第一个人出队,概率为p3.
4、服务器崩塌,终止,概率为p4.
求某人排在第m的位置,求服务器崩塌时他前面有少于k个人的概率。
解题思路:
之前做过类似的概率dp,有迭代,高斯消元解方程,不是顺序的,不过没写博客,所以就没做出来。。囧
因为人数有变化,所以人数要设一维,然后该人的位置也在变化,设为第二维。
dp[i][j]表示共有i个人,该人排在第j的位置时,发生所求事件的概率。
当j==1时,该人有1、2、4三种选择,dp[i][1]=p1*dp[i][1]+p2*dp[i][i]+p4
当2=<j<=k时,第一个人有1、2、3、4中选择使得事件发生,dp[i][j]=p1*dp[i][j]+p2*dp[i][j-1]+p3*dp[i-1][j-1]+p4
当j>k时,第一个人有1、2、3种选择使得事件发生,dp[i][j]=p1*dp[i][j]+p2*dp[i][j-1]+p3*dp[i-1][j-1],
化简得:
j==1 dp[i][j]=pp2*dp[i][i]+pp4
2=<j<=k dp[i][j]=pp2*dp[i][j-1]+pp3*dp[i-1][j-1]+pp4
j>k时,dp[i][j]=pp2*dp[i][j-1]+pp3*dp[i-1][j-1]
dp[1][1]可以直接求。
从dp[1]递推求出dp[i]
然后对于每一个dp[i] ,先把其他未知数带入dp[i][j]方程,迭代求出dp[i][j].
然后用依次递推求出dp[i][j].
代码:
#include<iostream>#include<cmath>#include<cstdio>#include<cstdlib>#include<string>#include<cstring>#include<algorithm>#include<vector>#include<map>#include<set>#include<stack>#include<list>#include<queue>#define eps 1e-8#define INF 0x1f1f1f1f#define PI acos(-1.0)#define ll __int64#define lson l,m,(rt<<1)#define rson m+1,r,(rt<<1)|1#pragma comment(linker, "/STACK:1024000000,1024000000")using namespace std;//freopen("data.in","r",stdin);//freopen("data.out","w",stdout);#define Maxn 2005double dp[Maxn][Maxn]; //dp[i][j]表示一共有i个人,该人排在第j位时的发生所求事件的概率double p1,p2,p3,p4,temp[Maxn]; //temp[i]表示求dp[i][j] 时前面一层的常数double pp[Maxn];//pp[i]表示pp^i,用于迭代求出dp[i][i];int n,m,k;int main(){ double pp2,pp3,pp4; while(~scanf("%d%d%d",&n,&m,&k)) { scanf("%lf%lf%lf%lf",&p1,&p2,&p3,&p4); if(p4<=eps) //最后一步肯定要*P4 ,如果p4很小的话,直接输出0.00000 { puts("0.00000"); continue; } pp2=p2/(1-p1);pp3=p3/(1-p1); pp4=p4/(1-p1); pp[0]=1.0; for(int i=1;i<=n;i++) pp[i]=pp[i-1]*pp2; //用于迭代保存系数 dp[1][1]=p4/(1-p1-p2); //根据方程1很快可以求出 for(int i=2;i<=n;i++) { temp[1]=pp4; for(int j=2;j<=k;j++) temp[j]=pp3*dp[i-1][j-1]+pp4; for(int j=k+1;j<=i;j++) temp[j]=pp3*dp[i-1][j-1];//第j个方程的常数 double tmp=0.0;//求出只含dp[i][i]未知数方程的常数部分 for(int j=i;j>=1;j--) tmp+=temp[j]*pp[i-j]; //把前面的方程带入后面的方程中 dp[i][i]=tmp/(1-pp[i]); dp[i][1]=pp2*dp[i][i]+temp[1]; //带入方程求出后面未知数的值 for(int j=2;j<i;j++) dp[i][j]=pp2*dp[i][j-1]+temp[j]; } printf("%0.5f\n",dp[n][m]); } return 0;}
- HDU 4089 Activation(概率DP)
- hdu 4089 Activation 概率DP
- 概率dp-hdu-4089-Activation
- [HDU 4089]Activation[概率DP]
- 概率dp HDU 4089 Activation
- hdu-4089-Activation-概率dp
- 【HDU】 4089 Activation 概率DP
- hdu 4089 Activation 概率dp
- 概率DP hdu 4089 Activation
- HDU 4089 Activation(概率DP)
- HDU 4089 Activation 概率dp
- HDU 4089 Activation【概率DP】
- HDU-4089 Activation(概率DP)
- Hdu 4089 Activation 概率DP
- hdu 4089 Activation(概率dp)
- hdu 4089 Activation(概率dp)
- hdu 4089 Activation 概率dp 消元
- Hdu 4089 Activation(概率DP)
- 防止死锁
- Segmentation fault
- jQuery选择器总结
- LeetCode - Set Matrix Zeroes
- iOS 开发者必知的 75 个工具(译文)
- 概率dp-hdu-4089-Activation
- Microsoft Help Viewer 2.0使用
- set_task_state()与__set_task_state()的区别
- Linux Shell基础知识7 循环语句
- android屏幕适配3
- 内存区划分、内存分配、常量存储区、堆、栈、自由存储区、全局区[
- 排序算法_计数排序
- 网站制作栏目的规划
- 消息 5070 在其他用户正式用数据库“”时无法更改数据库状态