1. 程式人生 > >Scout YYF I(矩陣優化dp)

Scout YYF I(矩陣優化dp)

題目:

我是超連結

題意:

主人公有p的機率走一步,1-p的機率走兩步,主人公一開始在格子1,給出地雷的位置,請問安全通過的概率是多少

題解:

概率與期望第一彈,但是這道題體現的基本是矩陣優化思想,那就當是矩陣題做一下

dp[i]表示到第i個格子安全的概率,不難發現:dp[i]=dp[i-1]*p+dp[i-2]*(1-p)

但是這樣i太大了,我們不如矩陣優化一下

dp[i]       | p ,1-p  |n-1    dp[1]
             =|            |  *
dp[i-1]    | 1 , 0    |         dp[0]

程式碼:

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
using namespace std;
struct hh
{
	double cr[3][3];
};
int a[12];
double p;
hh work(hh a,hh b)
{
	hh c;
	int i,j,k;
	memset(c.cr,0,sizeof(c.cr));
	for (i=1;i<=2;i++)
	  for (j=1;j<=2;j++) 
	    for (k=1;k<=2;k++)
	      c.cr[i][j]=(c.cr[i][j]+a.cr[i][k]*b.cr[k][j]);
	return c;
}
double pow(int pp)
{
	hh x,ans;
	memset(ans.cr,0,sizeof(ans.cr));
	x.cr[1][1]=p; x.cr[1][2]=1-p;
	x.cr[2][1]=1; x.cr[2][2]=0;
	ans.cr[1][1]=1;
	ans.cr[2][1]=0;
	for (;pp;pp>>=1,x=work(x,x))
	  if (pp&1) ans=work(ans,x);
	return ans.cr[1][1];
}
int main()
{
	int n,i;
	while (~scanf("%d%lf",&n,&p))
	{
	  for (i=1;i<=n;i++)
	    scanf("%d",&a[i]);
	  sort(a+1,a+n+1);
	  double rr=1.0;
	  for (i=1;i<=n;i++)
	    rr*=(1-pow(a[i]-a[i-1]-1));
	  printf("%.7f\n",rr);
	}
}