#There are some simple C function
Last active
July 13, 2016 02:54
-
-
Save allenyllee/acdf5af563018e46fe9a to your computer and use it in GitHub Desktop.
There are some simple C function
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
問題:假設記憶遊戲使用12張牌,6對(112233445566) | |
規則為每次翻兩張,相同就保留,不同就蓋回背面 | |
給六次機會,請問用程式算翻出6對~1對的機率為何? | |
**/ | |
/** | |
不記牌的抽中機率 | |
m:總共的牌組數(兩張一組) | |
n:可以翻牌的次數(一次兩張) | |
j:必須翻中同組的次數 | |
example: P1(6,5,4)= 牌面上有6組牌,可以抽5次,抽中4組的機率(每次翻完不記牌) | |
**/ | |
double P1(int m, int n, int j){ | |
double A=0,B=0, a1=0, a2=0; | |
/* | |
1. 總牌組數為負的機率是0 (m<0) | |
2. 可翻牌次數為負的機率是0 (n<0) | |
3. 翻中次數為負的機率是0 (j<0) | |
4. 翻中次數大於總牌組數的機率是0 (j>m) | |
5. 翻中次數大於可翻次數的機率是0 (j>n) | |
*/ | |
if( m<0 || n<0 || j<0 || j>m || j>n ) return 0; | |
//可翻次數為0時,翻中0次的機率為1 (j<=n=0) | |
if(j==0 && n==0) return 1; | |
a1 = 1/(2*m-1); //目前的牌面上,隨機翻中一組的機率 | |
a2 = 1-a1; //目前的牌面上,隨機翻不中的機率 | |
//A. 這一次有翻中,牌面剩下m-1組,可以翻的次數剩下n-1,翻中的次數剩下j-1 | |
//B. 這一次沒翻中,牌面剩下m組,可以翻的次數剩下n-1,翻中的次數剩下j | |
A = a1*P1(m-1,n-1,j-1); | |
B = a2*P1(m,n-1,j); | |
return A+B; | |
} | |
/** | |
有記牌的抽中機率 | |
m:總共的牌組數(兩張一組) | |
n:可以翻牌的次數(一次兩張) | |
j:必須翻中同組的次數 | |
k:已翻開不成對的張數(每次翻牌,成對的就拿走,不成對的就記下) | |
example: P2(6,5,4,3)= 牌面上有6組牌,已翻開3張不成對,可以抽5次,抽中4組的機率 | |
**/ | |
double P2(int m, int n, int j, int k){ | |
double A=0, B=0, C=0, D=0, a1=0, a2=0, b1=0, b2=0, b3=0; | |
/* | |
1. 總牌組數為負的機率是0 (m<0) | |
2. 可翻牌次數為負的機率是0 (n<0) | |
3. 翻中次數為負的機率是0 (j<0) | |
4. 翻中次數大於總牌組數的機率是0 (j>m) | |
5. 翻中次數大於可翻次數的機率是0 (j>n) | |
6. 不成對張數大於總牌組數的機率是0 (k>m) | |
7. 不成對張數為負的機率是0 (k<0) | |
*/ | |
if( m<0 || n<0 || j<0 || j>m || j>n || k>m || k<0 ) return 0; | |
//不成對張數與總牌組數相同(剩下的隨便翻都可配成一對),剩下n次翻中n次的機率為1 (k=m and j=n) | |
if(k==m && j==n && n<=m) return 1; | |
a1 = k/(2*m-k); //牌面上已知有k張不成對,從剩下的牌中翻開一張與這k張中某一張成對的機率 | |
a2 = 1-a1; //牌面上已知有k張不成對,從剩下的牌中翻開一張與這k張都不成對的機率 | |
b1 = 1/(2*m-k-1); //接續a2,再翻開一張與a2翻出來成對的機率 | |
b2 = k/(2*m-k-1); //接續a2,再翻開一張與前面k張成對的機率 | |
b3 = 1-b1-b2; //接續a2,再翻開一張與前面k張和a2翻出來的都不成對的機率 | |
/* | |
A. 已知牌面上有k張不成對,從其他牌中翻開一張,剛好與那k張中的某一張成對, | |
牌面剩下m-1組,可以翻的次數剩下n-1,翻中的次數剩下j-1,已知不成對的張數剩下k-1 | |
B. 已知牌面上有k張不成對,從其他牌中翻開一張,與那k張皆不成對, | |
再翻開一張與剛才翻出來的成對, | |
牌面剩下m-1組,可以翻的次數剩下n-1,翻中的次數剩下j-1,已知不成對的張數剩下k(沒變) | |
C. 已知牌面上有k張不成對,從其他牌中翻開一張,與那k張皆不成對, | |
再翻開一張與前面k張成對,因此到下一輪就可將翻到成對的兩張拿走, | |
牌面剩下m-1組,可以翻的次數剩下n-2(多花一次),翻中的次數剩下j-1,已知不成對的張數剩下k(沒變) | |
D. 已知牌面上有k張不成對,從其他牌中翻開一張,與那k張皆不成對, | |
再翻開一張與前面k張和剛才翻出的都不成對, | |
牌面剩下m組,可以翻的次數剩下n-1,翻中的次數剩下j,已知不成對的張數變成k+2 | |
*/ | |
A = a1*P2(m-1,n-1,j-1,k-1); | |
B = a2*b1*P2(m-1,n-1,j-1,k); | |
C = a2*b2*1*P2(m-1,n-2,j-1,k); | |
D = a2*b3*P2(m,n-1,j,k+2); | |
return A+B+C+D; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment