HDU3853 LOOPS 概率DP数学期望
HDU3853 LOOPS 概率DP
题目大意:
给出一个n * m的矩阵,要求从左上角走到右下角,每次移动消耗两点能量,并且每次的移动方向是有概率的(回到自身,往右或者往下)。输入的矩阵中的每个位置有三个数,分别表示回到自身、向右移动、向下移动的概率,三者概率和为1,要求输出从左上角走到右下角需要消耗的能量值的期望。(测试数据可能有点问题,会出现回到自身的概率为1从而导致死循环的情况)
解题思路:
每一个位置到终点的能量消耗期望,和向右或向下移动之后走到的位置开始走到终点消耗的能量期望有关,所以可以用DP来做。由于有一定概率会回到自身,所以就会提升一定难度,不过用数学方法推导一下就好了。
状态转移方程:DP[ i ][ j ] = (posi [ y ] * DP[ i ][ j+1 ] + posi [ z ] * DP[ i+1][ j ] + 2) / (1-posi [ a ])
其中posi [ a ]、posi [ b ]、posi [ c ]分别表示回到自身、到右边的位置、到下面的位置的概率
状态转移方程的推导:
假设当前位置为( x , y )回到自身的概率为a,向右移动的概率为b,向下移动的概率为c
且a + b + c = 1 , a >= 0 , b >= 0 , c >= 0;
因为存在多次先回到自身再向其他方向移动的情况,所以向右或向下移动所消耗的能量和回到自身的次数相关,存在以下关系:
DP[x][y]=limn→+∞∑i=1n[ai−1⋅b(2i+DP[x][y+1]+ai−1⋅c(2i+DP[x+1][y])]DP[ x ][ y ] = \lim_{n \rightarrow+\infty} \sum_{i=1}^n [a^{i-1}\cdot b(2i+DP[x][y+1]+a^{i-1}\cdot c(2i + DP[x+1][y])] DP[x][y]=n→+∞limi=1∑n[ai−1⋅b(2i+DP[x][y+1]+ai−1⋅c(2i+DP[x+1][y])]
把需要求和的每一项分开,发现是两个同型的等比数列and两个同型等差数列和等比数列的乘积,再分别计算求和得到下面的式子:
DP[x][y]=limn→+∞[(b⋅DP[x][y+1]+c⋅DP[x+1][y])⋅1−an−11−a+2⋅(1−an1−a−(n−1)⋅an)]DP[x][y] = \lim_{n \rightarrow+\infty}[(b\cdot DP[x][y+1]+c\cdot DP[x+1][y])\cdot
\frac{1-a^{n-1}}{1-a}+2\cdot (\frac{1-a^n}{1-a}-(n-1)\cdot a^n) ]DP[x][y]=n→+∞lim[(b⋅DP[x][y+1]+c⋅DP[x+1][y])⋅1−a1−an−1+2⋅(1−a1−an−(n−1)⋅an)]
∵limn→+∞1−an−1=limn→+∞1−an=1 limn→+∞an=0 limn→+∞n⋅an=0 (0<=a<1)∵ \lim_{n\rightarrow +\infty}1-a^{n-1}= \lim_{n \to+\infty}1-a^n=1 \ \ \ \ \ \ \ \ \ \ \lim_{n\to+\infty}a^n=0\ \ \ \ \ \ \ \ \ \lim_{n\to+\infty}n\cdot a^n=0\ \ \ \ \ \ (0<=a<1)∵n→+∞lim1−an−1=n→+∞lim1−a<
20000
span class="vlist-t">n=1 n→+∞liman=0 n→+∞limn⋅an=0 (0<=a<1)
∴DP[x][y]=b⋅DP[x][y+1]+c⋅DP[x+1][y]+21−a∴DP[x][y] = \frac{b\cdot DP[x][y+1]+c\cdot DP[x+1][y]+2}{1-a}∴DP[x][y]=1−ab⋅DP[x][y+1]+c⋅DP[x+1][y]+2
AC代码:
#include<cstdio> #include<cstring> using namespace std; static const int maxn = 1111; struct Node{ double x,y,z; }; int n,m; struct Node node[maxn][maxn]; double dp[maxn][maxn]; double solve(int x,int y){ if(x==n&&y==m||x>n||y>m) return 0; if(dp[x][y]!=0) return dp[x][y]; if(node[x][y].x==1) return dp[x][y] = 0; //题目数据问题 return dp[x][y] = (2+node[x][y].y*solve(x,y+1)+node[x][y].z*solve(x+1,y))/(1-node[x][y].x); } int main(){ while(scanf("%d %d",&n,&m)!=EOF){ for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ scanf("%lf %lf %lf",&node[i][j].x,&node[i][j].y,&node[i][j].z); } } memset(dp,0,sizeof(dp)); printf("%.3f\n",solve(1,1)); } return 0; }
- hdu3853 LOOPS 概率dp求期望
- HDU3853:LOOPS(概率dp & 期望)
- hdu3853[LOOPS] 继续浅尝期望概率DP
- HDU3853-LOOPS(概率DP求期望)
- hdu3853 LOOPS 【概率DP+期望问题】
- HDU3853-LOOPS(概率DP求期望)
- Uva 11427 Expect the Expected 概率dp 求数学期望
- 动态规划练习题:概率DP总结,求解数学期望或概率的题目
- HDU3853--LOOPS--概率DP
- 【期望DP】HDU3853 LOOPS
- HDU-3853 LOOPS(概率DP求期望)
- SGU495Kids and Prizes(数学期望||概率DP||公式)
- hdu 3853 LOOPS(概率 dp 期望)
- 借助树的概率dp(期望)+数学-好题-hdu-4035-Maze
- dp 求数学期望 概率 HDU - 5236
- HDU3853:LOOPS(概率DP)
- [poj2096] Collecting Bugs【概率dp 数学期望】
- [hdu4035] Maze【概率dp 数学期望】
- 简单概率dp(期望)-hdu-3853-LOOPS
- UVa 11427 Expect the Expected (数学期望 + 概率DP)