題意:
你在一條布滿地雷的道路上,開始在座標1。每次有概率p向前走一步,有概率1-p向前走兩步。道中路某幾個點上會有地雷,問你安全通過的概率。地雷數n<=10,座標範圍在100000000內。
假設dp[i]表示安全走到i點的概率,那麼dp[i]=p*dp[i-1]+(1-p)*dp[i-2]。很簡單的乙個轉移,可是偏偏座標範圍太大了。直接遞推爆記憶體,而且肯定也會超時。
我們換乙個思路,假設x[i]表示第i個地雷的座標。對於任何兩個地雷x[i]~~x[i-1]+1之間,只會有乙個地雷,那就是x[i]。我們安全通過該段的概率等於1 減去猜到x[i]的概率。
也就是說,我們將n個地雷分成n段分別處理。每次都可以得到乙個安全通過某一段的概率,最後將這些概率乘起來就是答案了。
可是萬一兩個地雷之間差的很遠怎麼辦呢?記憶體和時間還不是一樣的不允許?
於是我們用矩陣來優化一下。想想超大fibonacci數的矩陣求法,f[i]=f[i-1]+f[i-2]。f[n]等價於矩陣
| 1 1 |
| 1 0 |
的n次方以後,矩陣的第a[0,0]個元素。
同樣的,我們為這個dp[i]=p*dp[i-1]+(1-p)*dp[i-2]構造乙個矩陣
| p ,1-p |
| 1 , 0 |
那麼dp[n]就是該矩陣n次方後的第a[0,0]個元素。
通過二分運算,飛快的就可以求出答案了
view code
1 #include2 #include3 #include4
using
namespace
std;56
struct
mat7
16};
1718
mat e;
19int n,x[11
];20
double
p;21
22mat mul(mat a,mat b)
2332
33void
prit(mat a)
3442}43
44double matpow(mat a,int
k)45
53 a=mul(a,a);
54 k=k>>1;55
}56//prit(ans);
57return ans.a[0][0
];58}59
60int
main()
6179 printf("
%0.7lf\n
",ans);80}
81return0;
82 }
poj3744 概率dp 矩陣乘法
在一條路上有n個地雷,有個sb人按照心情走在這條路上,往前走1步的概率是p,往前走2步的概率是 1 p 求他活著走過這條路的概率。很容易想到一種dp方程 f i p f i 1 1 p f i 2 然而一看範圍 1,100000000 怎麼可能不超時呢 然後可以這麼想 只要避開了最後乙個地雷不就安全...
poj 3744 概率dp 矩陣快速冪
poj 3744 題目大概是 小明要走一段路 有p的概率走一步 1 p 的概率走兩步 然後上面有雷 問安全通過的概率 題目通過雷把路程分為多段 把每段安全通過的概率相乘 就是整段安全通過的概率 設dp i 是小明安全到i的概率 到i的方式有兩種 一種是從 i 1 走一步 第二種是從 i 2 走兩步 ...
POJ3744題解 概率dp,矩陣快速冪
士兵從起點1出發,每次移動有p的概率走一步,有1 p的概率走兩步,已知有n個格仔有地雷,問士兵不踩地雷的概率。第一道真正意義上的概率dp題目,一開始打算令dp i 意為更新到i點時踩雷的概率,dp i p dp i 1 1 p dp i 2 這樣寫看上去也是對的 第一眼看上去的角度上來說 但是其實並...