JLOI2013 卡牌遊戲

2021-08-21 07:16:53 字數 2544 閱讀 7769

讀完題可以很容易的想到暴力模擬,列舉每一張卡片,然後看誰被淘汰,去掉被淘汰的人後從他的下乙個人開始重複上面的操作,直到剩下乙個人,那麼乙個人獲勝的概率就是他贏的狀態數除以總狀態數,複雜度為o(n

!)

o(n!)

o(n!

),直接t

tt飛。

考慮優化,我們發現複雜度主要是被人的編號所約束,因為我們在考慮乙個人獲勝的情況時,還具體考慮了其他人存活的情況和是哪個人現在坐莊。事實上這些考慮都是多餘的,因為卡牌上數字的意思是當前坐莊的人向後第幾個,並不是人的編號,所以只要我們知道現在是第幾輪(或者知道現在還剩下多少人),坐莊的是第幾個,要求勝利的人處在第幾個位置,那麼就可以列舉卡片,找到被淘汰的人的位置,然後根據被淘汰的人的位置推出下一輪坐莊的人的位置和要求勝利的人的位置(若被淘汰的人是要求勝利的人,那麼跳過這次列舉的卡片),這樣就可以快速地進行轉移了。

令f [i

][j]

[k

]f[i][j][k]

f[i][j

][k]

表示當前是第i

ii輪(或者也可以定義為還剩有i

ii個人,不過**略有改動),坐莊的是第j

jj個,要求勝利的人處在第k

kk個位置時獲勝的概率。對於每乙個情況,列舉卡牌進行轉移,令當前卡牌淘汰的人是第p

pp個,那麼分下面幾種情況:

f [i

][j]

[k]=

f[i]

[j][

k]+f

[i+1

][p]

[k−1

]×1m

f[i][j][k]=f[i][j][k]+f[i+1][p][k-1]×\frac

f[i][j

][k]

=f[i

][j]

[k]+

f[i+

1][p

][k−

1]×m

1​

f[i][j][k]=f[i][j][k]+f[i+1][p][k]×\frac(p≠n-i+1)\\f[i][j][k]=f[i][j][k]+f[i+1][1][k]×\frac(p=n-i+1) \end

for(

int i=

0;i1;i++

)printf

("%.2lf%% "

,f[1][

0][i]*

100)

;printf

("%.2lf%%\n"

,f[1][

0][n-1]*

100)

;return0;

}嘗試能不能進一步優化,觀察**發現只有可能優化掉對坐莊的人的列舉,因為另外兩維都很重要,若坐莊人的位置在每一輪都是同樣的位置,那麼就能優化掉。不過坐莊人的位置一直在變,怎麼優化?事實上我們需要的只是剩餘人數和坐莊人與要求獲勝的人的相對位置,所以我們可以假設每次坐莊人都在第乙個位置,轉移的話就是相當於把下一次的坐莊人的位置看成是第乙個,那麼要求勝利的人的位置也要相對移動。相對移動的位置自己畫一下就能發現規律,定義f[i

][j]

f[i][j]

f[i][j

]表示當前是第i

ii輪(或者定義為還剩有i

ii個人,**會略有改動),要求勝利的人處在第j

jj個位置時獲勝的概率,令p

pp為被淘汰的人的位置,下面給出轉移:

f[i][j]=f[i][j](p=j)\\f[i][j]=f[i][j]+f[i+1][j-p]×\frac(pj)\end

⎩⎪⎨⎪⎧​

f[i]

[j]=

f[i]

[j](

p=j)

f[i]

[j]=

f[i]

[j]+

f[i+

1][j

−p]×

m1​(

pf[i]

[j]=

f[i]

[j]+

f[i+

1][n

−i+1

−p+j

]×m1

​(p>j)

​ 複雜度約為o(n

2m

)o(n^2m)

o(n2m)

#include

#include

#include

#include

using

namespace std;

const

int n=51;

double f[n]

[n];

int n,m,card[n]

;int

main()

for(

int i=

0;i1;i++

)printf

("%.2lf%% "

,f[1

][i]

*100);

printf

("%.2lf%%\n"

,f[1

][n-1]

*100);

return0;

}

JLOI2013 卡牌遊戲

jloi2013 卡牌遊戲 n個人坐成一圈玩遊戲。一開始我們把所有玩家按順時針從1到n編號。首先第一回合是玩家1作為莊家。每個回合莊家都會隨機 即按相等的概率 從卡牌堆裡選擇一張卡片,假設卡片上的數字為x,則莊家首先把卡片上的數字向所有玩家展示,然後按順時針從莊家位置數第x個人將被處決即退出遊戲。然...

JLOI2013 卡牌遊戲

傳送門 這個題一開始不會轉移了 因為自己狀態設定的不對。應該參考一下約瑟夫問題的操作,設dp i j 表示在有i個人的時候從莊家開始數第j個人的獲勝概率。這樣的話,我們只要列舉每張卡牌,這樣的話,每個人獲勝的概率就能由有i 1個人的時候推出來,因為其實淘汰乙個人就是相當於把佇列向前移動幾位,但是勝利...

JLOI2013 卡牌遊戲

n個人坐成一圈玩遊戲。一開始我們把所有玩家按順時針從1到n編號。首先第一回合是玩家1作為莊家。每個回合莊家都會隨機 即按相等的概率 從卡牌堆裡選擇一張卡片,假設卡片上的數字為x,則莊家首先把卡片上的數字向所有玩家展示,然後按順時針從莊家位置數第x個人將被處決即退出遊戲。然後卡片將會被放回卡牌堆裡並重...