题解 [JLOI2013] 卡牌游戏
主要思路:
玩家id为[0,n-1],枚举到i玩家,将其临时id当成0,则初始庄家的临时id为(n-i),dp[i][j]表示i玩家坐庄,还剩j个人时的胜率
用记忆化搜索来实现
注意:
1.i号玩家出局时,下一次庄家的id即为i%(tot-1)(tot是当前玩家数)
分两种情况:i=tot-1时,下一次的庄家即为0,(tot-1)%(tot-1)==0;
i<tot-1时,下一次的庄家即为i,i%(tot-1)==i;
2.当转到0玩家,也就是当前求其胜率的人,continue
代码如下
#include <bits/stdc++.h>
using namespace std;
#define LL long long
int n,m,Num[510];
double dp[510][510];
int mark[510][510];
double dfs(int k,int p) {
k=k%p;//当k==p时,应从0玩家开始
if(mark[k][p])return dp[k][p];
int x;
double res=0;
for(int i=1; i<=m; ++i) {
x=(k+Num[i]-1)%p;
if(x!=0)res+=dfs(x,p-1)/(1.0*m);//x==0则舍去
}
mark[k][p]=1;
return dp[k][p]=res;
}
int main() {
cin>>n>>m;
for(int i=1; i<=m; ++i) {
scanf("%d",&Num[i]);
}
for(int i=0; i<n; ++i) {
memset(mark,0,sizeof mark);
memset(dp,0,sizeof dp);
mark[0][1]=1;//设置终止条件
dp[0][1]=1;
printf("%.2lf%%",100*dfs(n-i,n));//要求用百分数输出
if(i!=n-1)printf(" "); //printf输出‘%’需打两个%
}
return 0;
}

浙公网安备 33010602011771号