bzoj2510 矩陣乘法 DP 弱題

2021-09-10 10:00:36 字數 3612 閱讀 7860

description

有m個球,一開始每個球均有乙個初始標號,標號範圍為1~n且為整數,標號為i的球有ai個,並保證σai = m。

每次操作等概率取出乙個球(即取出每個球的概率均為1/m),若這個球標號為k(k < n),則將它重新標號為k +

1;若這個球標號為n,則將其重標號為1。(取出球后並不將其丟棄) 現在你需要求出,經過k次這樣的操作後,每個標號的球的期望個數。

input

第1行包含三個正整數n,m,k,表示了標號與球的個數以及操作次數。 第2行包含n個非負整數ai,表示初始標號為i的球有ai個。

output

應包含n行,第i行為標號為i的球的期望個數,四捨五入保留3位小數。

sample input

2 3 2

3 0

sample output

1.667

1.333

hint

【樣例說明】

第1次操作後,由於標號為2球個數為0,所以必然是乙個標號為1的球變為標號為2的球。所以有2個標號為1的球,有1個標號為2的球。

第2次操作後,有1/3的概率標號為2的球變為標號為1的球(此時標號為1的球有3個),有2/3的概率標號為1的球變為標號為2的球(此時標號為1的球有1個),所以標號為1的球的期望個數為1/33+2/31

= 5/3。同理可求出標號為2的球期望個數為4/3。

【資料規模與約定】

對於10%的資料,n ≤ 5, m ≤ 5, k ≤ 10;

對於20%的資料,n ≤ 20, m ≤ 50, k ≤ 20;

對於30%的資料,n ≤ 100, m ≤ 100, k ≤ 100;

對於40%的資料,m ≤ 1000, k ≤ 1000;

對於100%的資料,n ≤ 1000, m ≤ 100,000,000, k ≤ 2,147,483,647。

題解

並不知道這個東西

首先寫個暴力就可以驗證dp方程是

f [i

][j]

=f[i

−1][

j]∗m

−1m+

f[i−

1][p

re]∗

1mf[i][j]=f[i-1][j]*\frac+f[i-1][pre]*\frac

f[i][j

]=f[

i−1]

[j]∗

mm−1

​+f[

i−1]

[pre

]∗m1

​這個顯然可以寫成乙個矩乘的形式…

然後他是n3l

ogkn^3logk

n3logk

的…並不知道矩陣還有另一種方法優化到n

2n^2

n2,所以跪了

上圖是轉移矩陣,他乙個迴圈矩陣

注意到下面一行都是由上一行向右移一格得到的…

那麼有乙個性質,迴圈矩陣的次冪同樣是乙個迴圈矩陣

所以我們只需要儲存第一行的狀態是什麼,樸素矩乘是

f [i

][k]

=∑a[

i][j

]∗b[

j][k

]f[i][k]=\sum a[i][j]*b[j][k]

f[i][k

]=∑a

[i][

j]∗b

[j][

k]這裡矩乘的形式推一下就可以變為

f [k

]=∑a

[k]∗

b[k−

j+1]

f[k]=\sum a[k]*b[k-j+1]

f[k]=∑

a[k]

∗b[k

−j+1

]其中k−j

+1k-j+1

k−j+1在[1,

n][1,n]

[1,n

]中,如果小於1了就加個n

nn那麼快速冪就可以變為n2l

ogkn^2logk

n2logk

的,出來再做個樸素矩乘就可以了

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define ll long long

#define mp(x,y) make_pair(x,y)

#define pll pair

#define pii pair

using

namespace std;

inline

intread()

while

(ch>=

'0'&&ch<=

'9')

return x*f;

}int stack[20]

;inline

void

write

(ll x)if(

!x)int top=0;

while

(x)stack[

++top]

=x%10

,x/=10;

while

(top)

putchar

(stack[top--]+

'0');}

inline

void

pr1(

int x)

inline

void

pr2(ll x)

const

int maxn=

1005

;int n,m,k;

struct ma1

}st,tp1;

struct ma2

}tp2;

ma1 mul1

(ma1 u1,ma1 u2)

return ret;

}ma1 mul2

(ma2 u2,ma1 u1)

ma1 pow_mod

(ma1 u1,

int b)

return ret;

}int

main()

// puts("");

}// puts("");

st=mul2

(tp2,st)

;for

(int i=

1;i<=n;i++

)printf

("%.3lf\n"

,st.m[i]);

return0;

}

Bzoj2510 弱題(矩陣快速冪)

一道概率 dp 可以設 f i j 表示第 i 次操作後,標號為 j 的小球的期望個數,那麼有 begin f i j 1 frac 1m f i 1 j frac1mf i 1 j 1 1 leq j leq n f i 0 1 frac 1m f i 1 j frac1mf i 1 n end ...

矩陣鏈乘法 DP

矩陣鏈乘法是這樣的問題 給定n個矩陣 a1,a2,an,其中ai與ai 1是可乘的,i 1,2 n 1。確定計算矩陣連乘積的計算次序,使得依此次序計算矩陣連乘積需要的數乘次數最少。輸入資料為矩陣個數和每個矩陣規模,輸出結果為計算矩陣連乘積的計算次序和最少數乘次數。我們稱有如下性質的矩陣乘積鏈為完全括...

dp矩陣鏈乘法

dp矩陣鏈乘法 矩陣a和b可乘的條件是矩陣a的列數等於矩陣b的行數。給定n個矩陣 a1,a2,an 其中ai與ai 1是可乘的,i 1,2 n 1。如何確定計算矩陣連乘積的計算次序,使得依此次序計算矩陣連乘積需要的數乘次數最少。輸入描述 首先輸入乙個n,表示幾個矩陣。換行輸入矩陣。輸出描述先輸出矩陣...