poj3744高速功率矩阵+可能性DP

Scout YYF I

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 4410   Accepted: 1151

Description

YYF is a couragous scout. Now he is on a dangerous mission which is to penetrate into the enemy‘s base. After overcoming a series difficulties, YYF is now at the start of enemy‘s famous "mine road". This is a very long road, on which there are numbers of mines.
At first, YYF is at step one. For each step after that, YYF will walk one step with a probability of p, or jump two step with a probality of 1-p. Here is the task, given the place of each mine, please calculate the probality that YYF can
go through the "mine road" safely.

Input

The input contains many test cases ended with EOF.

Each test case contains two lines.

The First line of each test case is N (1 ≤ N ≤ 10) and p (0.25 ≤ p ≤ 0.75) seperated by a single blank, standing for the number of mines and the probability to walk one step.

The Second line of each test case is N integer standing for the place of N mines. Each integer is in the range of [1, 100000000].

Output

For each test case, output the probabilty in a single line with the precision to 7 digits after the decimal point.

Sample Input

1 0.5
2
2 0.5
2 4

Sample Output

0.5000000
0.2500000
/*分析:对于n个地雷s[1],s[2],s[3],s[4]...s[n]
如果s都是不递减的。

如果dp[i]表示从1到达i这个位置的概率
则:
dp[s[1]-1]为1~s[1]-1的概率//s[1]不能到达
dp[s[2]-1]为1~s[2]-1也是1->s[1]-1->s[1]+1->s[2]-1的概率
因为最多仅仅能跳两格
所以dp[s[i]+1]一定是从dp[s[i]-1]到达
然后从dp[s[i]+1]到达dp[s[i+1]-1];//这部分就能够用矩阵高速幂
另外依据公式dp[i]=p*dp[i-1]+(1-p)*dp[i-2]也可知从s[i]+1 => s[i+1]-1用矩阵高速幂求
构造初始矩阵:
p 1-p   *  dp[i]      =  dp[i+1]
1 0        dp[i-1]        dp[i]
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <queue>
#include <algorithm>
#include <map>
#include <cmath>
#include <iomanip>
#define INF 99999999
typedef long long LL;
using namespace std;

const int MAX=10+10;
const int N=2;
int n,s[MAX];
double array[N][N],sum[N][N],p;

void InitMatrix(){
	array[0][0]=p;
	array[0][1]=1-p;
	array[1][0]=1;
	array[1][1]=0;
	for(int i=0;i<N;++i){
		for(int j=0;j<N;++j)sum[i][j]=(i == j);
	}
}

void MatrixMult(double a[N][N],double b[N][N]){
	double c[N][N]={0};
	for(int i=0;i<N;++i){
		for(int j=0;j<N;++j){
			for(int k=0;k<N;++k){
				c[i][j]+=a[i][k]*b[k][j];
			}
		}
	}
	for(int i=0;i<N;++i)for(int j=0;j<N;++j)a[i][j]=c[i][j];
}

double Matrix(int k){
	if(k<0)return 0;//表示s[i-1]~s[i]之间无位置
	InitMatrix();//初始化矩阵
	while(k){//有k+1个位置,到达第k+1个位置所以是k次
		if(k&1)MatrixMult(sum,array);
		MatrixMult(array,array);
		k>>=1;
	}
	return sum[0][0];//sum[0][0]*dp[1]+sum[0][1]*dp[0]
}

int main(){
	while(~scanf("%d%lf",&n,&p)){
		for(int i=1;i<=n;++i)scanf("%d",&s[i]);
		sort(s+1,s+1+n);
		double ans=Matrix(s[1]-2);//1~s[1]-1的概率
		for(int i=2;i<=n;++i){
			if(s[i] == s[i-1])continue;
			double temp=Matrix(s[i]-s[i-1]-2);//s[i-1]~s[i]之间有s[i]-s[i-1]-1个位置,须要走s[i]-s[i-1]-2次到达最后一个位置
			ans=ans*(1-p)*temp;//从s[i-1]-1的位置跳两格到s[i-1]+1再到s[i]-1
		}
		printf("%.7f\n",ans*(1-p));//在s[n]-1位置还须要跳两格才安全了
	}
	return 0;
}

版权声明:本文博客原创文章,博客,未经同意,不得转载。

时间: 2024-11-17 18:00:14

poj3744高速功率矩阵+可能性DP的相关文章

开始了他的高速功率矩阵

通常用于加速复发. 简单地.为fib有列.f0 = 1.f1 = 1,fn = fn-1 + fn-2(n >= 2). 则对于fn有: 一般的.对于fn = A1*f(n-1) + A2*f(n-2)  + .... +A(n-1)*f1,有: 又由于矩阵乘法满足结合律,所以能够用高速幂来求A^n,从而达到递推的效果. 顺便即一个小技巧: 以POJ 3233为例 #include <algorithm> #include <iostream> #include <cs

bzoj 3120 矩阵优化DP

我的第一道需要程序建矩阵的矩阵优化DP. 题目可以将不同的p分开处理. 对于p==0 || p==1 直接是0或1 对于p>1,就要DP了.这里以p==3为例: 设dp[i][s1][s2][r]为前i列,结尾为0的有s1行(0表示女生,1表示男生),结尾为01的有s2个,结尾为011的有n-s1-s2个,有r列全是1的方案数. 状态这么复杂,看起来一点也不能用矩阵优化,但我们可以将状态(s1,s2,r)hash成整数,然后建立状态之间的转移. 收获: 这种m超过10^7的一般都要用矩阵优化,如

VOJ 1067 Warcraft III 守望者的烦恼 (矩阵高速功率+dp)

主题链接 明显的 dp[n] = dp[n-k] + dp[n-k+1] + ... +dp[n-1]; 然后要用矩阵来优化后面的状态转移. 也就是矩阵 0 1 0 0    a     b 0 0 1 0 * b =  c 0 0 0 1    c     d 1 1 1 1    d    a+b+c+d 然后跑高速幂 #include <iostream> #include <cstdio> #include <algorithm> #include <cm

HDU 2842 Chinese Rings(矩阵高速功率+递归)

职务地址:HDU 2842 这个游戏是一个九连环的游戏. 如果当前要卸下前n个环.由于要满足前n-2个都卸下,所以要先把前n-2个卸下.须要f(n-2)次.然后把第n个卸下须要1次,然后这时候要卸下第n-1个.然后此时前n-2个都已经被卸下了.这时候把前n-2个都卸下与都装上所需的次数是一样的.由于卸下与装上的规则是一样的. 所以又须要f(n-2)次.这时候前n-1个都在上面,卸下前n-1个须要f(n-1)次. 所以.总共须要2*f(n-2)+f(n-1)+1次. 然后构造例如以下矩阵. 1,2

[poj3744]Scout YYF I(概率dp+矩阵快速幂)

题意:在一维空间上存在一些雷,求安全通过的概率.其中人有$p$的概率前进一步,$1-p$的概率前进两步. 解题关键:若不考虑雷,则有转移方程:$dp[i] = p*dp[i - 1] + (1 - p)*dp[i - 2]$ 由于雷的数量很少,所以可以以雷为界,将区域分开,在每个区域中,通过该段的概率等于1-踩到该段终点的地雷的概率.然后用矩阵快速幂优化一下即可 1 #include<cstdio> 2 #include<cstring> 3 #include<algorit

POJ3744 Scout YYF I (概率DP + 矩阵优化)

题目链接: http://poj.org/problem?id=3744 题意: 有一段路,路上有n个陷阱,每一次只能向前走一步或者两步,求安全走过这段路的改路 分析: 设dp[i]表示安全走过第i个陷阱的概率 那么dp[i+1]=dp[i]*(1-p(走到第i+1个陷阱)) 因为每次只能走一步或者两步,所有安全走过第i个陷阱后的位置一定在a[i]+1;\ 其中a[i]表示第i个陷阱的位置 求从a[i]+1,走到a[i+1]的概率的时候我们需要用到矩阵来经行优化 ans[i]表示走到位置i的概率

POJ 3070 Fibonacci(矩阵高速功率)

职务地址:POJ 3070 用这个题学会了用矩阵高速幂来高速求斐波那契数. 依据上个公式可知,第1行第2列和第2行第1列的数都是第n个斐波那契数.所以构造矩阵.求高速幂就可以. 代码例如以下: #include <iostream> #include <cstdio> #include <string> #include <cstring> #include <stdlib.h> #include <math.h> #include

NYOJ 298 相变点(矩阵高速功率)

点的变换 时间限制:2000 ms  |  内存限制:65535 KB 难度:5 描写叙述 平面上有不超过10000个点.坐标都是已知的.如今可能对全部的点做下面几种操作: 平移一定距离(M),相对X轴上下翻转(X),相对Y轴左右翻转(Y),坐标缩小或放大一定的倍数(S),全部点对坐标原点逆时针旋转一定角度(R). 操作的次数不超过1000000次,求终于全部点的坐标. 提示:假设程序中用到PI的值,能够用acos(-1.0)获得. 输入 仅仅有一组測试数据 測试数据的第一行是两个整数N,M,分

矩阵乘法&amp;&amp;dp加速矩阵的思路(E. Wet Shark and Blocks)

There are b blocks of digits. Each one consisting of the same n digits, which are given to you in the input. Wet Shark must choose exactly one digit from each block and concatenate all of those digits together to form one large integer. For example,