【POJ】 3744 Scout YYF I 矩阵快速幂
来源:互联网 发布:linux给文件夹重命名 编辑:程序博客网 时间:2024/06/06 02:28
Scout YYF I
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 ofp, 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
POJ Monthly Contest - 2009.08.23, Simon 题目大意:给你N个地雷mine[N](均在x轴上)以及一个概率p(0.25 <= p <= 0.75) ,规定起始坐标为1。以x轴正方向为正向,p的概率正向移动一个单位,(1-p)的概率正向移动两位,问你有多少的概率使得不踩到任意一个地雷上。
题目分析:由递推公式易知走到第n个点的概率为F(n) = p * F(n - 1) + (1 - p) * F(n - 2)。
为此我们可以构造这样一个矩阵A = | p 1 |,可以得到 | F(n - 1) F(n - 2) | * | p 1 | = | F(n) F(n - 1) |。
| (1 - p) 0 | | (1 - p) 0 |
那么F(n)即为 A ^ n。规定A^0 = E(单位矩阵)。
假设第一个地雷坐标为i, 第二个地雷坐标为j。那么从起点开始踩到第i个地雷的概率为F(i - 1), 那么不踩到 i 的概率为1 - F(i - 1)。因为不踩到 i ,所以接下来必定从第 i + 1 开始走,那么在不踩到 i 的前提下踩到到 j 的概率为(1 - F(i - 1)) * F(j - i - 1), 同样的既不踩到 i 又不踩到 j 的概率即(1 - F(i - 1)) * (1 - F(j - i - 1))。
所以最终答案即(1 - F(mine[1] - 1)) * (1 - F(mine[2] - 1) * ... * (1 - F(mine[n] - 1))。
需要注意的是有两种必死的情况:起始点出现地雷或者出现两个地雷相连。
- Time Limit: 1000MS
- Memory Limit: 65536K
- Total Submissions: 4452
- Accepted: 1159
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 ofp, 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.522 0.52 4
Sample Output0.50000000.2500000
SourcePOJ Monthly Contest - 2009.08.23, Simon
题目分析:由递推公式易知走到第n个点的概率为F(n) = p * F(n - 1) + (1 - p) * F(n - 2)。
为此我们可以构造这样一个矩阵A = | p 1 |,可以得到 | F(n - 1) F(n - 2) | * | p 1 | = | F(n) F(n - 1) |。
| (1 - p) 0 | | (1 - p) 0 |
那么F(n)即为 A ^ n。规定A^0 = E(单位矩阵)。
假设第一个地雷坐标为i, 第二个地雷坐标为j。那么从起点开始踩到第i个地雷的概率为F(i - 1), 那么不踩到 i 的概率为1 - F(i - 1)。因为不踩到 i ,所以接下来必定从第 i + 1 开始走,那么在不踩到 i 的前提下踩到到 j 的概率为(1 - F(i - 1)) * F(j - i - 1), 同样的既不踩到 i 又不踩到 j 的概率即(1 - F(i - 1)) * (1 - F(j - i - 1))。
所以最终答案即(1 - F(mine[1] - 1)) * (1 - F(mine[2] - 1) * ... * (1 - F(mine[n] - 1))。
需要注意的是有两种必死的情况:起始点出现地雷或者出现两个地雷相连。
代码如下:
#include <stdio.h>#include <algorithm>#define REP(i, n) for(int i = 0; i < n; ++i)#define FF(i, n) for(int i = 1; i <= n; ++i)using namespace std;const int O = 2;int N;struct Matrix{ typedef double type; type mat[O][O]; Matrix operator * (const Matrix &t) const{ Matrix tmp; REP(i, N) REP(j, N){ tmp.mat[i][j] = 0; REP(k, N){ tmp.mat[i][j] = (tmp.mat[i][j] + mat[i][k] * t.mat[k][j]); } } return tmp; } Matrix operator + (const Matrix &t) const{ Matrix tmp; REP(i, N) REP(j, N){ tmp.mat[i][j] = (mat[i][j] + t.mat[i][j]); } return tmp; } Matrix operator - (const Matrix &t) const{ Matrix tmp; REP(i, N) REP(j, N){ tmp.mat[i][j] = (mat[i][j] - t.mat[i][j]); } return tmp; }};Matrix E, A;Matrix pow(Matrix a, int k){ Matrix res = E, tmp = a; while(k){ if(k & 1) res = res * tmp; tmp = tmp * tmp; k >>= 1; } return res;}int work(){ int n, mine[11], flag; double p, ans; N = O; mine[0] = 0; REP(i, N) REP(j, N) E.mat[i][j] = (i == j); while(~scanf("%d%lf", &n, &p)){ FF(i, n) scanf("%d", &mine[i]); sort(mine + 1, mine + n + 1); flag = 0; FF(i, n){ if(mine[i] - mine[i - 1] == 1) flag = 1; } if(mine[0] == 1 || flag){ printf("%.7f\n", 0); continue; } A.mat[0][0] = p; A.mat[0][1] = 1; A.mat[1][0] = 1 - p; A.mat[1][1] = 0; ans = 1; FF(i, n){ if(mine[i] == mine[i - 1]) continue; ans *= 1 - pow(A, mine[i] - mine[i - 1] - 1).mat[0][0]; } printf("%.7f\n", ans); } return 0;}int main(){ return work();}
0 0
- POJ 3744 Scout YYF I Scout YYF I (递推+矩阵快速幂)
- POJ 3744 Scout YYF I 矩阵快速幂加速dp
- poj 3744 Scout YYF I(概率DP&矩阵快速幂)
- poj 3744 Scout YYF I(概率dp+矩阵快速幂)
- 【POJ】 3744 Scout YYF I 矩阵快速幂
- POJ 3744 Scout YYF I 概率DP + 矩阵快速幂
- poj 3744 Scout YYF I(概率dp+矩阵快速幂)
- POJ 3744 Scout YYF I 概率dp+矩阵快速幂
- POJ 3744 Scout YYF I 概率dp 矩阵快速幂
- POJ 3744 Scout YYF I (概率DP+矩阵快速幂)
- poj 3744 Scout YYF I(矩阵快速幂优化dp)
- poj 3744 Scout YYF I 矩阵快速幂 概率论
- POJ 3744 Scout YYF I 矩阵快速幂+概率dp
- POJ-3744 Scout YYF I [概率DP][矩阵快速幂]
- POJ 3711 Scout YYF I 概率DP + 矩阵快速幂
- poj 3744 Scout YYF I 矩阵
- poj-3744-Scout YYF I-矩阵乘法
- poj 3744 Scout YYF I (矩阵快速幂+概率dp)
- 【HDU】 4089 Activation 概率DP
- 【POJ】 2049 Finding Nemo BFS
- 【ACDream】 1093 女神的正多面体 矩阵快速幂
- 【HDU】 4833 Best Financing DP
- 【HDU】 4831 Scenic Popularity 暴力模拟
- 【POJ】 3744 Scout YYF I 矩阵快速幂
- 【HDU】 4832 Chess 排列组合 DP
- 【UVa】 10735 Euler Circuit 混合图的欧拉回路 最大流
- 【HDU】 3395 Special Fish 费用流(可KM匹配)
- 【HDU】 2448 Mining Station on the Sea 费用流
- 【POJ】 1986 Distance Queries 离线LCA
- 【POJ】 2135 Farm Tour 费用流
- 【POJ】 2516 Minimum Cost 费用流
- 【HDU】 4067 Random Maze 费用流