Python程式:透過一些操作找到給定陣列子陣列的期望和
程式:透過一些操作找到給定陣列子陣列的期望和
假設我們有一個大小為n的陣列A和兩個值p和q。我們可以對A執行以下操作。
- 隨機選擇兩個索引(l, r),其中l < r,然後交換A[l]和A[r]
- 隨機選擇兩個索引(l, r),其中l < r,然後反轉A從索引l到r的子陣列。
在執行p次第一個操作和q次第二個操作之後,我們隨機選擇兩個索引l和r,其中l < r,並計算S = A[l..r]的所有元素的和,然後我們必須找到S的期望值。
因此,如果輸入類似於A = [1,2,3] p = 1 q = 1,則輸出將為4.667,因為
步驟1:我們有三個選擇:
交換(0, 1),所以陣列將變為2 1 3
交換(0, 2),所以陣列將變為3 2 1
交換(1, 2),所以陣列將變為1 3 2
步驟2:對於每個結果,我們再次有三個選擇:
[2 1 3] 變為 [1 2 3],[3 1 2],[2 3 1]
[3 2 1] 變為 [2 3 1],[1 2 3],[3 1 2]
[1 3 2] 變為 [3 1 2],[2 3 1],[1 2 3]
共有9個可能的陣列,因此機率為1/9。所以這9個數組中的每一個都將具有3個具有相同機率的可能和。例如,對於[1 2 3],我們可以得到1+2、2+3和1+2+3。對於此輸入,總共有27個結果,可以透過找到所有27個S的和並將其除以27來計算期望值。
為了解決這個問題,我們將遵循以下步驟:
- 定義一個函式matmul()。這將接收a, v, n
- toret := 一個大小為n的陣列,並用0填充
- 對於i in range 0 到 n - 1,執行
- 對於j in range 0 到 n - 1,執行
- toret[i] := toret[i] + a[i, j]*v[j]
- 對於j in range 0 到 n - 1,執行
- 返回toret
- 從主方法中,執行以下操作
- n := A的大小
- temp := 一個新的列表
- swp := (n - 3) /(n - 1)
- swapvalp := ((swp^p)*(n - 1) + 1) /n
- swapvalm :=(1 - (swp^p)) /n
- rev := 一個新的空列表
- dotv := 一個新的空列表
- 對於i in range 0 到 n - 1,執行
- swaprow := 一個新的空列表
- revrow := 一個新的空列表
- 對於j in range 0 到 n - 1,執行
- 在swaprow的末尾插入swapvalm
- 在revrow的末尾插入2*(min(i, j, (n-i-1) 和 (n-j-1+1))/(n*(n - 1))
- swaprow := 一個新的空列表
- revrow := 一個新的空列表
- 對於j in range 0 到 n - 1,執行
- swaprow[i] := swapvalp
- revrow[i] := 1.0 - 2*((i + 1)*(n - i) - min((i+1) 和 (n - i)))/(n*(n-1))
- 在temp的末尾插入swaprow
- 在rev的末尾插入revrow
- 在dotv的末尾插入2*((i+1)*(n-i) - 1)/(n*(n-1))
- A := matmul(temp, A, n)
- 對於i in range 0 到 q,執行
- A := matmul(rev, A, n)
- tot := 0.0
- 對於i in range 0 到 n,執行
- tot := tot + dotv[i]*A[i]
- 返回tot
示例
讓我們看看下面的實現以更好地理解:
def matmul(a, v, n): toret = [0]*n for i in range(n): for j in range(n): toret[i] += a[i][j]*v[j] return toret def solve(A, p, q): n = len(A) temp = [] swp = (n - 3)/(n - 1) swapvalp = (pow(swp, p)*(n - 1) + 1)/n swapvalm = (1 - pow(swp, p))/n rev = [] dotv = [] for i in range(n): swaprow = [] revrow = [] for j in range(n): swaprow.append(swapvalm) revrow.append(2*(min(i, j, n - i - 1, n - j - 1) + 1)/(n*(n - 1))) swaprow[i] = swapvalp revrow[i] = 1.0 - 2*((i + 1)*(n - i) - min(i + 1, n - i))/(n*(n - 1)) temp.append(swaprow) rev.append(revrow) dotv.append(2*((i + 1)*(n - i) - 1)/(n*(n - 1))) A = matmul(temp, A, n) for _ in range(q): A = matmul(rev, A, n) tot = 0.0 for i in range(n): tot += dotv[i]*A[i] return tot A = [1,2,3] p = 1 q = 1 print(solve(A, p, q))
輸入
[1,2,3], 1, 1
輸出
0.0
廣告