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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

icpc网络赛第二场K Meal

發(fā)布時(shí)間:2023/12/3 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 icpc网络赛第二场K Meal 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

icpc網(wǎng)絡(luò)賽第二場K Meal

題意:

有n個(gè)人,n個(gè)菜,
現(xiàn)在n個(gè)人輪流吃菜,起初S中有n個(gè)菜,第i個(gè)人會(huì)在還沒拿走的菜中隨機(jī)選一個(gè),拿走第j個(gè)菜的概率為ai,j∑k∈Sai,k\frac{a_{i,j}}{\sum_{k∈S}a_{i,k}}kS?ai,k?ai,j??,然后將這個(gè)菜從集合S中刪除,如果S為空則結(jié)束,否則輪到下一個(gè)繼續(xù)拿菜
讓你輸出第i個(gè)人拿第j個(gè)菜的概率
n<=20 ,ai,ja_{i,j}ai,j?<=100

題解:

比賽時(shí)想好大體思路,好不容易把A寫完,調(diào)了半天,最后沒時(shí)間做K了
題意很好理解,對(duì)于不同的拿取方式,對(duì)于第i個(gè)人的情況是不同的,不難看出n很小才20,所以我們可以狀壓dp
我們枚舉二進(jìn)制,1表示這個(gè)菜被取了,0表示還未取
對(duì)于一個(gè)狀態(tài)state,假設(shè)共cnt個(gè)位置為1,因?yàn)槭琼樞虺圆?#xff0c;所以就是求第cnt個(gè)人的吃菜概率,枚舉其中為1的位置,相當(dāng)于是吃的第j種菜
用f[i]表示當(dāng)前這個(gè)選菜局面的概率,i的二進(jìn)制狀態(tài)下表示菜的選取情況
利用之前的f[]來轉(zhuǎn)移現(xiàn)在的ans[][],用現(xiàn)在的選取狀態(tài)來更新當(dāng)前的f[]
這樣得到轉(zhuǎn)移方程:

ans[cnt][j]=(ans[cnt][j]+f[i^(1ll<<j)]*a[cnt][j]%mod*inv[sum[cnt]-tot+a[cnt][j]])%mod; f[i]=(f[i]+f[i^(1ll<<j)]*a[cnt][j]%mod*inv[sum[cnt]-tot+a[cnt][j]])%mod;

這樣復(fù)雜度為O(n*2n),注意因?yàn)閍很小,所以求逆元不要用快速冪,會(huì)超時(shí),直接O(n)預(yù)處理好即可

代碼:

#include<bits/stdc++.h> using namespace std; typedef long long ll; #define int long long #define x first #define y second typedef pair<int,int> pii; const int N=21;int dp[N][1<<N]; int a[N][N]; int f[1<<N]; int ans[N][N]; int sum[N]; int inv[30000000]; const int mod= 998244353; int qmi(int a,int b) {int res=1;while(b){if(b&1) res=res*a%mod;b>>=1;a=a*a%mod;}return res; } void init(){inv[1]=1;for(int i=2;i<=2000;++i)inv[i]=mod-(long long)mod/i*inv[mod%i]%mod; } signed main() {int n;cin >> n;init();for(int i=1;i<=n;i++) {for(int j=0;j<n;j++) cin >> a[i][j],sum[i]=(sum[i]+a[i][j])%mod;}f[0]=1;for(int i=1;i<1<<n;i++){int cnt=0;int tot=0;for(int j=0;j<n;j++)if(i>>j&1) cnt++;for(int j=0;j<n;j++)if(i>>j&1) tot=(tot+a[cnt][j])%mod;for(int j=0;j<n;j++){if(i>>j&1){ // cout<<"sum[cnt]-?tot+a[cnt][j]="<<sum[cnt]-tot+a[cnt][j]<<endl;ans[cnt][j]=(ans[cnt][j]+f[i^(1ll<<j)]*a[cnt][j]%mod*inv[sum[cnt]-tot+a[cnt][j]])%mod;f[i]=(f[i]+f[i^(1ll<<j)]*a[cnt][j]%mod*inv[sum[cnt]-tot+a[cnt][j]])%mod;}} // cout<<f[i]<<endl;}for(int i=1;i<=n;i++){for(int j=0;j<n;j++)if(j==0)cout<<ans[i][j];else cout<<" "<<ans[i][j];cout<<endl;} }

總結(jié)

以上是生活随笔為你收集整理的icpc网络赛第二场K Meal的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。