時間限制: 1 sec 記憶體限制: 128 mb
有m個球,一開始每個球均有乙個初始標號,標號範圍為1~n且為整數,標號為i的球有ai個,並保證σai = m。
每次操作等概率取出乙個球(即取出每個球的概率均為1/m),若這個球標號為k(k
< n),則將它重新標號為k + 1;若這個球標號為n,則將其重標號為1。(取出球后並不將其丟棄)
現在你需要求出,經過k次這樣的操作後,每個標號的球的期望個數。
第1行包含三個正整數
n,m,k,表示了標號與球的個數以及操作次數。
第2行包含n個非負整數
ai,表示初始標號為i的球有ai個。
應包含n行,第i行為標號為i的球的期望個數,四捨五入保留3位小數。
2 3 23 0
1.6671.333
這道題很容易就能想到用矩陣快速冪,但n^3的時間複雜度顯然是過不去,然後根據dp方程 f[i]=a/n*f[i-1]+(1-b/n)*f[i];所以每一項的轉移都是從本位和前一位轉移而來的,那麼在構建出來的矩陣,無論自乘多少次都能地i+1行是由i行右移的得到的,最後一位到第一位;那麼就可以用矩陣的第一行來表示整個矩陣,我實現的有些麻煩,我有把整個矩陣都重現了出來,其實可以直接由乙個關係直接轉移,還有進一步的優化空間;
(
1 #include2 #include3 #include4 #include5 #include6 #include7 #include8using
namespace
std;
9int
n,m,k;
10int num[1010
];11
double f[1010
];12
double a[1010][1010
];13
double cc[1010
];14
double b[1010][1010
];15
void
cheng1()21}
22for(int i=1;i<=n;i++)
23 f[i]=cc[i];24}
25double dd[1010][1010
];26
void
cheng2()32}
33for(int i=1;i<=n;i++)
34 a[1][i]=dd[1
][i];
35for(int i=2;i<=n;i++)
41 a[i][j]=a[i-1][j-1
];42}43
}44}45
void
cheng3()52}
53for(int i=1;i<=n;i++)
56for(int i=2;i<=n;i++)
62 b[i][j]=b[i-1][j-1
];63}64
}65//while(1);66}
67int
main()
75for(int i=1;i<=n;i++) b[i][i]=1
;76 a[1][1]+=(double)(m-1)/m;
77 a[n][1]+=(double)1/m;
78for(int i=2;i<=n;i++)
82/*
83for(int i=1;i<=n;i++)
87cout<88}*/
89while
(k)93
cheng2();
94 k=k>>1;95
}96cheng1();
97for(int i=1;i<=n;i++)
100return0;
101 }
迴圈矩陣留坑)
bzoj2510 矩陣乘法 DP 弱題
description 有m個球,一開始每個球均有乙個初始標號,標號範圍為1 n且為整數,標號為i的球有ai個,並保證 ai m。每次操作等概率取出乙個球 即取出每個球的概率均為1 m 若這個球標號為k k n 則將它重新標號為k 1 若這個球標號為n,則將其重標號為1。取出球后並不將其丟棄 現在你...
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 ...
樹狀陣列訓練題1 弱弱的戰壕(vijos1066)
這道題似乎是vijos上能找到的最簡單的樹狀陣列題了。原來,我有乙個錯誤的思想,我的設計是維護兩個樹狀陣列,乙個是橫座標,乙個是縱座標,然後讀入每個點的座標,扔進對應的樹狀陣列內,然後計算時,只要以當前點的座標為末點求字首和,在兩個字首和中取最小的乙個即可。但是這個想法很明顯有錯誤比如如圖的狀況 此...