日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

概率期望学习笔记

發(fā)布時間:2023/12/3 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 概率期望学习笔记 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

概率期望學習筆記


POJ3869

題意:兩個人轉左輪手槍,朝自己打,槍里保證至少有一個空的,你的對手上一輪活下來了,現(xiàn)在到你了,問重新轉左輪和直接打,哪個概率高。

做法:考慮00,10,兩種串,即可計算不轉時,下一個為空的概率。重新轉的概率,就是這個手槍里所有空的位置比所有的口的個數。注意串是循環(huán)的。

#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #define rep(i,a,b) for(int i=(a);i<=(b);++i) #define per(i,a,b) for(int i=(a);i>=(b);--i) #define pb push_back typedef long long ll; typedef double LD; const int N = 2000000; using namespace std; char s[N]; int main() {scanf(" %s",s+1);int n = strlen(s+1),l=1,r=n,num0=0,num1=0;rep(ti,1,n) {if(s[r-1]=='0'&&s[r]=='0')++num0;if(s[r-1]=='1'&&s[r]=='0')++num1;++r; s[r]=s[l]; ++l;}if(num0*n>(num1+num0)*(num1+num0))puts("SHOOT");else if(num0*n<(num1+num0)*(num1+num0))puts("ROTATE");else puts("EQUAL");return 0; }

POJ2794

題意:有9組牌,每組4張,兩張牌的大小一樣時可以消掉,每次只能消掉最上面的牌,然后一個在玩的時候如果有多種消法,就會隨機選擇其中一種,問他將所有牌都消掉的幾率是多少。

做法:用一個9位5進制數表示當前的狀態(tài),直接記憶化搜索即可。一開始的寫法T了。

#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #define rep(i,a,b) for(int i=(a);i<=(b);++i) #define per(i,a,b) for(int i=(a);i>=(b);--i) #define pb push_back typedef long long ll; typedef double LD; const int N = 2000000; using namespace std; int a[20][20], M[266], num[9], A[9], f[22], ST, vis[N]; LD dp[N]; char s1[4]; double solve(int s) {if(vis[s]) return dp[s];vis[s]=1;int A[9],tmp=0;rep(i,0,8) A[i]=(s/f[i])%5;rep(i,1,8)rep(j,0,i-1) {if(A[i]&&A[j]&&a[i][A[i]]==a[j][A[j]]) {dp[s] += solve(s-f[i]-f[j]);++tmp;}}if(tmp)dp[s]/=(double)tmp;return dp[s]; }int main() {f[0]=1; rep(i,1,9)f[i]=f[i-1]*5;ST = f[9]-1;M['6']=0;M['7']=1;M['8']=2;M['9']=3;M['T']=4;M['J']=5;M['Q']=6;M['K']=7;M['A']=8;rep(i,0,8)rep(j,1,4) {scanf(" %s",s1);a[i][j] = M[s1[0]];}vis[0]=1; dp[0]=1.0;cout << solve(ST) << '\n';//TLE // memset(dp,0,sizeof(dp)); // int x,y,t,z,tmp;LD tt; // dp[ST]=1.0; // per(s,ST,0) { // z = 0;tmp=0; // rep(i,0,8) { // x = (s/f[i])%5; // if(num[a[i][x]]==0)num[a[i][x]]=1,++tmp; // z+=x; // } // memset(num,0,sizeof(num)); // if(tmp==9)continue; // if(z&1)continue; // tmp=0; // rep(j,0,8) {x = (s/f[j])%5; if(x>0)++num[a[j][x]];} // rep(j,0,8) if(num[j]>=2) tmp += (1*(num[j]*(num[j]-1))>>1); // tt = (LD)dp[s]/tmp; // // rep(j,0,8) A[j]=(s/f[j])%5; // rep(j,1,8)rep(k,0,j-1) { // x=A[k], y=A[j]; // if(x!=0&&y!=0&&a[j][y]==a[k][x]){ // t = s; t-=(f[k]+f[j]); // dp[t] += tt; // } // } // } // printf("%f\n",(double)dp[0]);return 0; }

Codeforces1009E

題意:給定序列a,要求把長度n,劃分成一些段,每一段的值形如a1,a2,..,求這些值和的期望。

做法:考慮每一個位置的期望。對于位置i,值為a1,只有它的前面恰好是一個分界線;值為a2,即他向前一個的位置恰好是個分界線;同理,可以列數位置i的值的期望為:
\(E_i = \frac{a_1}{2^{1}} + \frac{a_2}{2^{2}} + ... + \frac{a_{i-1}}{2^{i-1}} + \frac {a_i}{2^{i-1}}\)
\(E_1 = a_1\)
\(E_2 = \frac{a_1}{2^{1}} + \frac {a_2}{2^{1}}\)
\(E_3 = \frac{a_1}{2^{1}} + \frac{a_2}{2^{2}} + \frac {a_3}{2^{2}}\)
$E_4 = \frac{a_1}{2^{1}} + \frac{a_2}{2^{2}} + \frac {a_3}{2^{3}} + \frac {a_4}{2^{3}} $
直接求和即可。

#include <bits/stdc++.h> #define rep(i,a,b) for(int i=a;i<=b;++i) #define per(i,a,b) for(int i=a;i>=b;--i) #define pb push_back typedef long long ll; const int N = 1e6 + 7; const ll mod = 998244353; using namespace std; int n; ll a[N],ans=0,f[N];int main() {scanf("%d",&n);f[0]=1;rep(i,1,n)f[i]=(f[i-1]*2LL)%mod;rep(i,1,n) scanf("%I64d",&a[i]);rep(i,1,n) {ll t;if(i<n) t = ((a[i]*f[n-i])%mod + (a[i]*((f[n-i-1]*(n-i))%mod))%mod)%mod;else t = (a[i]*f[n-i])%mod;ans=(ans+t%mod)%mod;}printf("%I64d\n",ans);return 0; }

Codeforces930B

題意:給定一個串,對他循環(huán)移位,通過首字母和一個后邊的字母判斷移了多少位,問成功的概率。

做法:對每種移位情況下,枚舉每次去查哪個位置,對每種字母找到最好的位置。即使得盡可能多的情況下,這個位置的字母是不同的,使得成功的概率更高。設字母\(c_i\)的最優(yōu)的情況后邊有\(num_i\)個位置,字母唯一,\(c_i\)的個數為\(cnt(c_i)\),所以以這種字母開頭,成功概率為\(\frac{num_i}{cnt(c_i)}\),把所有字母累加起來就是:\(\sum {\frac{num_i}{cnt(c_i)}·\frac {cnt(c_i)}{n}} = \frac {\sum {num_i}}{n}\)

#include <bits/stdc++.h> #define rep(i,a,b) for(int i=a;i<=b;++i) #define per(i,a,b) for(int i=a;i>=b;--i) #define pb push_back typedef long long ll; const int N = 5005; using namespace std; int n,ff[N],num[26]; char s[N<<1]; vector<int> v[26]; int main() {scanf(" %s",s+1);n = strlen(s+1);rep(i,1,n) s[i+n]=s[i];rep(i,1,n) v[s[i]-'a'].pb(i);rep(i,0,25)rep(x,1,n-1){int f=0;memset(num,0,sizeof(num));for(auto p: v[i]) ++num[s[p+x]-'a'];int tt = 0;rep(j,0,25)if(num[j]==1)++tt;ff[i]=max(ff[i],tt);}int tmp = 0;rep(i,0,25)tmp+=ff[i];printf("%.10f\n",1.0*tmp/(double)n);return 0; }

Codeforces935D

題意:給定兩個序列S1, S2,他們有一些位置的值是確定的,一些是不確定的,可以填入1~m中的數,問S1比S2字典序高的概率。

做法:從高位到低位遞推,dp[i][0]表示前i個位置S1等于S2的概率,dp[i][1]表示前i個位置,S1大于S2的概率。分情況討論,直接做即可。

#include <bits/stdc++.h> #define rep(i,a,b) for(int i=a;i<=b;++i) #define per(i,a,b) for(int i=a;i>=b;--i) #define pb push_back typedef long long ll; const int N = 1e5 + 7; const int mod = 1e9 + 7; using namespace std; ll n,m,a[N],b[N],dp[N][2],invm,invmm,inv2; ll q_pow(ll a,ll b) {a%=mod;ll ans = 1;while(b) {if(b&1) ans=(ans*a)%mod;a=(a*a)%mod;b>>=1;}return ans; } ll P(int i,int opt) {if(!opt) {if(a[i]&&b[i]&&a[i]==b[i]) return 1LL;if(a[i]&&b[i]&&a[i]!=b[i]) return 0LL;if(!a[i]&&b[i]) return invm%mod;if(a[i]&&!b[i]) return invm%mod;if(!a[i]&&!b[i]) return invm%mod;}else {if(a[i]&&b[i]&&a[i]>b[i]) return 1LL;if(a[i]&&b[i]&&a[i]<=b[i]) return 0LL;if(!a[i]&&b[i]) return ((m-b[i])%mod*invm)%mod;if(a[i]&&!b[i]) return ((a[i]-1LL)%mod*invm)%mod;if(!a[i]&&!b[i]) return ((((((m-1LL)%mod)*m)%mod*inv2)%mod)*invmm)%mod;} }int main() {scanf("%I64d%I64d",&n,&m);inv2 = q_pow(2LL,mod-2);invm = q_pow(m,mod-2);invmm = (invm*invm)%mod;rep(i,1,n)scanf("%I64d",&a[n-i+1]);rep(i,1,n)scanf("%I64d",&b[n-i+1]);dp[1][0]=P(1,0), dp[1][1]=P(1,1);rep(i,2,n) {dp[i][0] = (P(i,0)*dp[i-1][0])%mod;dp[i][1] = (P(i,1) + (P(i,0)*dp[i-1][1])%mod)%mod;}(dp[n][1]+=mod)%=mod;printf("%I64d\n",dp[n][1]);return 0; }

Codeforces280C

題意:給定一棵樹,每次操作可以刪除一顆子樹。問期望的操作次數。

題解:考慮每個點對答案的貢獻,點i最終一定會被刪除,如果刪除它的時候,是在刪除它的祖先,則他對答案無貢獻,如果是通過自己刪的,則對答案有貢獻。能刪除它的祖先共有:這個點的深度-1 個點。所以點u的期望就是\(\frac{1}{deep[u]}\),最后累加起來。一開始,推出了深度是1的樹的公式,然后推廣了一下,寫的自底向上算。。結果gg,這題思路真的有點神。

#include <bits/stdc++.h> #define rep(i,a,b) for(int i=a;i<=b;++i) #define per(i,a,b) for(int i=a;i>=b;--i) typedef long long ll; const int N = 1e5 +7; using namespace std; struct edge{int e,nxt;}E[N<<1]; int cc,h[N]; void add(int u,int v) {E[cc].e=v;E[cc].nxt=h[u];h[u]=cc;++cc;} int n,dep[N]; double ans = 0; void dfs(int u,int pre) {ans += 1.0/dep[u];for(int i=h[u];~i;i=E[i].nxt) if(E[i].e!=pre) {dep[E[i].e] = dep[u] + 1;dfs(E[i].e,u);} } int main() {scanf("%d",&n);rep(i,1,n) h[i] = -1;rep(i,1,n-1) {int x,y;scanf("%d%d",&x,&y);add(x,y), add(y,x);}dep[1] = 1; dfs(1,0);printf("%.12f\n",ans);return 0; }

Codeforces452C

題意:把n副一樣的牌混在一起,每副牌包含m張,從其中選n張,問取兩次牌相同的概率。

做法:考慮一種牌x的貢獻,枚舉x的個數k,現(xiàn)在先從n*m張牌中挑n張,其中有k張x,然后再考慮從中兩次選出x的概率,可以列出式子:\[\sum_{k=1}^{min(m,n)} \frac {C^k_m·C_{nm-m}^{n-k}·k^2}{C_{nm}^n·n}\]

#include <bits/stdc++.h> #define rep(i,a,b) for(int i=a;i<=b;++i) #define per(i,a,b) for(int i=a;i>=b;--i) typedef long long ll; const int N = 1e5 +7; using namespace std; int n,m; int main() {scanf("%d%d",&n,&m);double Cnmn = 1.0, Cmx = m, Cnm_x = 1.0, ans = 0;rep(i,1,n) Cnmn = Cnmn * (n*m - i + 1)/i;rep(i,1,n-1) Cnm_x = Cnm_x * ((n-1.0)*m - i + 1)/i;rep(i,1,min(n,m)) {ans += Cmx*Cnm_x*i*i/Cnmn/n;Cmx = Cmx * (m - (i+1) + 1.0)/(i+1);Cnm_x = Cnm_x * (n-(i+1)+1)/((n-1.0)*m - (n-(i+1)+1) + 1);}printf("%.10f\n",ans);return 0; }

Codeforces261B

\(f[i][j][k]\)表示前i個元素取j個,構成體積k的方法數,枚舉最后放不進去的元素是哪個,每種情況對答案的貢獻,就是\(\sum {f[n][j][k]·j!·(n-j-1)!}\),計算f[i][j][k]的時候記得不要放x,最后的答案除\(n!\),和背包一樣,\(i\) 這一維可以去掉,j和k都相當于一種體積。。。智商逐漸消失。。

#include <bits/stdc++.h> #define rep(i,a,b) for(int i=a;i<=b;++i) #define per(i,a,b) for(int i=a;i>=b;--i) #define pb push_back typedef long long ll; const int N = 52; using namespace std; int n,a[N],p,sum; double f[N][N], ans, fc[N]; // (前i個元素)取j個,構成體積k的方法數int main() {scanf("%d",&n);rep(i,1,n) scanf("%d",&a[i]),sum+=a[i];scanf("%d",&p);fc[0] = 1.0;rep(i,1,n) fc[i]=fc[i-1]*i;if(sum <= p) {printf("%.10f\n",(double)n);}else {rep(x,1,n) { // 枚舉那個恰好沒被使用的元素memset(f,0,sizeof(f));rep(i,0,n) f[0][0] = 1;rep(i,1,n) {per(k,p,a[i]) per(j,i,1) {if(i!=x)f[j][k] += f[j-1][k-a[i]];}}rep(i,0,n-1) rep(k,max(p-a[x]+1,0),p) {ans += f[i][k]*fc[i]*fc[n-i-1]*i;}}ans /= fc[n];printf("%.10f\n",ans);}return 0; }

轉載于:https://www.cnblogs.com/RRRR-wys/p/9385616.html

總結

以上是生活随笔為你收集整理的概率期望学习笔记的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。