好仙的題目啊,本來是kmp裡的題但最後該用的地方被我用hash艹過去了算了反正這不是這道題的重點
考慮乙個暴力的\(o((nm)^3)\)的做法,其實就是bzoj 1444: [jsoi2009]有趣的遊戲的弱化版,但在這道題中直接上只能得到40pts
我們考慮一下這個方法為什麼不行,其實主要的原因是狀態實在太多了
考慮到實際上有意義的狀態只有\(n\)個,其餘的狀態都可以合併成乙個——「不合法的狀態」
乍一看是不是很亂來?怎麼能把那麼多不同的狀態歸為一類?
沒事我們來找個情況分析一下,在這之前先放乙個顯然的引理:
引理:構造乙個指定的長度為\(l\)的\(01\)串的概率是\(\frac\)考慮現在\(s\)是乙個不合法的狀態(即沒有人獲勝),\(a=101\),\(b=110\)
那麼我們假定遊戲進行到到\(s+101\)的狀態,那麼此時遊戲一定會停止,但不一定要等到\(101\)加完才停止
很顯然我們可以看出當\(s\)的字尾是\(1\)或者\(10\)時遊戲會提前結束,換句話說會有這些情況:
\[s+101=(s+a)+(s'+a+01)+(s''+b+1)
\]其中\(s=s'+10=s''+1\)
那麼我們根據上面的引理,可以得到乙個方程:
\[\fracs=a+\fraca+\fracb
\]是不是很神奇,但仔細一想我們發現這確實包含了所有情況,那麼我們來試著形式化一下這鐘方法:
對於每乙個字串\(s_i\),設它獲勝的概率是\(p_i\),不合法(即永遠無法結束)的輔助狀態的概率設為\(s\)
我們發現對於另乙個字串\(s_j\),若\(s_j\)存在長度為\(k\)的字尾能匹配\(s_i\)的字首,那麼就有\(\frac}\)的概率提前結束
那麼我們在設\(pre_\)表示字串\(s_i\)長度為\(j\)的字首,\(suf_\)表示字串\(s_i\)長度為\(j\)的字尾
那麼對於每乙個\(s_i\),我們都將\(s+s_i\)作為一次終止狀態列個方程,即:
\[\sum_^n\sum_^m [pre_=suf_]\frac} p_j=\fracs
\]但這樣只有\(n\)個方程,但變數有\(n+1\)個。我們發現其實遊戲必然會結束,即\(s=0\),所以可以列出最後乙個方程:\(\sum_^n p_i=1\),然後就上高消即可,複雜度\(o(n^3)\)
ps:那個匹配字首字尾可以用kmp,但我比較懶因此寫了hash
pps:這題非常開精度,如果你得到了40pts的好成績請把高消寫成精度更高的方法,並且在bzoj上由於沒有spj,因此eps
要調到\(10^\)
#include#include#include#define ri register int
#define ci const int&
using namespace std;
typedef unsigned long long u64;
const int n=305;
const double eps=1e-10;
struct hasher
friend inline bool operator == (const hasher& a,const hasher& b)
friend inline hasher operator + (const hasher& a,const hasher& b)
friend inline hasher operator * (const hasher& a,const hasher& b)
}pw[n],pre[n][n],suf[n][n]; int n,m; double pw2[n],p[n][n],val[n]; char s[n];
const hasher seed=hasher(233,167);
inline void gauss(ci n)
}for (val[n]/=p[n][n],i=n-1;i;--i)
}int main()
for (i=1;i<=n;++i) for (j=1;j<=n;++j) for (k=1;k<=m;++k)
if (pre[i][k]==suf[j][m-k+1]) p[i][j]+=pw2[m-k];
for (i=1;i<=n;++i) p[i][n+1]=-pw2[m],p[n+1][i]=1; val[n+1]=1;
for (gauss(n+1),i=1;i<=n;++i) printf("%.10lf\n",val[i]);
return 0;
}
bzoj 4820 硬幣遊戲
週末同學們非常無聊,有人提議,咱們扔硬幣玩吧,誰扔的硬幣正面次數多誰勝利。大家紛紛覺得這個遊戲非常符 合同學們的特色,但只是扔硬幣實在是太單調了。同學們覺得要加強趣味性,所以要找乙個同學扔很多很多次硬幣 其他同學記錄下正反面情況。用h表示正面朝上,用t表示反面朝上,扔很多次硬幣後,會得到乙個硬幣序列...
Bzoj 2726 SDOI 任務安排
memory limit 131072kb 64bit io format lld llu description 機器上有n個需要處理的任務,它們構成了乙個序列。這些任務被標號為1到n,因此序列的排列為1,2,3.n。這n個任務被分成若干批,每批包含相鄰的若干任務。從時刻0開始,這些任務被分批加工...
BZOJ 3991 SDOI2015 尋寶遊戲
題目大意 給定一棵樹,其中有若干個關鍵點,任意選擇起點,求從起點出發訪問所有關鍵點又回到起點的最小邊權總和,有m個修改操作,每次修改乙個關鍵點。假如沒有修改操作的話,就像乙個簡單的樹形dp,方程如下 f i sigma sigma.觀察一下dp的過程,就是不斷地從前面的點走到後面的點,所以我們可以不...