1. 程式人生 > >【BZOJ】3191 [JLOI2013]卡牌遊戲(概率dp)

【BZOJ】3191 [JLOI2013]卡牌遊戲(概率dp)

如果 style ++ bzoj mem color con size oid

題目

傳送門:QWQ

分析

算是概率dp不錯的題。

$ dp[i][j] $表示有i個人時,這i個人中的第j個獲勝的概率。

我們把i從1推到n,那麽答案就是$ dp[n][i] $

然後我們規定,第一個人就是莊。

然後我們枚舉每個卡片tmp。

$ dp[i][j]=dp[i][j] + dp[i-1][j-tmp]/m $

如果$ tmp>j $,那麽也一樣推一推就ok了。

代碼

#include <bits/stdc++.h>
using namespace std;
const int maxn=60;
int  a[maxn];
double dp[maxn][maxn]; void plu(int i){int x;scanf("%d",&x);a[i]=x;} int main(){ int n,M;scanf("%d%d",&n,&M); double m=M; memset(dp,0,sizeof(dp)); dp[1][1]=1.0; for(int i=1;i<=m;i++) plu(i); for(int i=2;i<=n;i++){ for(int j=1;j<=i;j++){
for(int k=1;k<=m;k++){ int t=a[k]%i; if(!t) t=i; if(j>t) dp[i][j]+=dp[i-1][j-t]/m; if(j<t) dp[i][j]+=dp[i-1][i-t+j]/m; } } } for(int i=1;i<=n;i++){ dp[n][i]*=100.0; printf("%.2f",dp[n][i]);putchar(
%);putchar( ); } return 0; }

【BZOJ】3191 [JLOI2013]卡牌遊戲(概率dp)