【BZOJ】3191 [JLOI2013]卡牌游戏(概率dp)
题目
传送门: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; }