寫在前面
演算法思路
由於每一行都只有四張牌,考慮寫成五進製狀壓 dp。
設當前狀態為 \(t\),則五進製狀壓 dp 取出第 \(i\) 行的狀態的方式:\(\frac\!\!\!\!\mod 5\)(視初始行為第 \(0\) 行)
因此,若設第 \(i\) 行的第 \(j\) 張牌的點數為 \(a_\),則狀態轉移方程為:
\[\large f_ - 5^} = f_ - 5^} + f_t \times p(a_\!\!\!\!\mod 5} = a_\!\!\!\!\mod 5})
\]其中 \(p\) 為此次轉移的概率,等於從狀態 \(t\) 能轉移到的狀態數總和的倒數。
邊界條件: \(f_ = 1\)。
倒序列舉所有狀態,每當找到乙個當前答案不為 \(0\) 的狀態時,先統計出它能更新到的狀態數,算出轉移的概率 \(p\),然後用該狀態去更新它所能更新到的狀態的答案。
由於一直在拿牌,表示狀態的變數會逐漸減小,倒序列舉狀態時可行的。
tips
code
#include#define lf double
const int pow5 = ;
using namespace std;
lf f[1953125];
int a[10][5];
char getch()
int main()
} f[1953124] = 1.0;
for(register int t = pow5[9] - 1; t >= 0; --t)
} lf p = f[t] * 1.0 / choise;
for(register int p1 = 0; p1 < 9; ++p1)
}} }
printf("%lf", f[0]);
return 0;
}
P1123 均分紙牌
有 n 堆紙牌,編號分別為 1,2,n。每堆上有若干張,但紙牌總數必為 n 的倍數。可以在任一堆上取若於張紙牌,然後移動。移牌規則為 在編號為 1 堆上取的紙牌,只能移到編號為 2 的堆上 在編號為 n 的堆上取的紙牌,只能移到編號為 n 1 的堆上 其他堆上取的紙牌,可以移到相鄰左邊或右邊的堆上。...
P1031 均分紙牌
有 nn 堆紙牌,編號分別為 1,2,n1,2,n 每堆上有若干張,但紙牌總數必為 nn 的倍數。可以在任一堆上取若干張紙牌,然後移動。移牌規則為 在編號為 11 堆上取的紙牌,只能移到編號為 22 的堆上 在編號為 nn 的堆上取的紙牌,只能移到編號為 n 1n 1 的堆上 其他堆上取的紙牌,可以...
P1031 均分紙牌
這道題我想的方法很麻煩。是乙個模擬。模擬的操作 遍歷一遍陣列,從左到右遇到大於平均值往後分攤,中途遇到大於平均數的數直接都分到這裡。遇到小於平均值的,往後疊小於平均值的數,遇到大於的數就分一點過去,直到比平均值差的值都被分攤完。這樣是線性的,主要操作是第二步,負的疊起來加上去等價於反向傳回來,如果提...