bzoj 3191: [JLOI2013]卡牌游戏

来源:互联网 发布:韦东山linux第一期 编辑:程序博客网 时间:2024/06/07 20:25

题意:

问每一个人在约瑟夫问题胜出的概率。

题解:

一开始我想了个三维的dp。
然后被tybD。
其实不难发现,真正有价值的是当前计算的人与当前庄家的距离。
所以设f[i][j]表示剩下i个人,离庄家距离为j的人胜出的期望。
随便转移下就好了。
code:

#include<cstdio>#include<cstdlib>#include<cstring>#include<iostream>using namespace std;double f[55][55];int n,m,a[55];int dis(int x,int y,int num) {return (y-x+num)%num;}//在num个人的情况下,y里x的距离double dfs(int x,int y)//x个人,距离庄家y的人赢的期望。 {    if(x==1) return 1.0;    if(f[x][y]!=-1) return f[x][y];    f[x][y]=0;    for(int i=1;i<=m;i++)    {        int p=a[i]%x;//下一个庄家到当前庄家的距离        if((y+1)%x==p) continue;        int Y=y;        if(p!=0) {p--;if(p<Y) Y--;}        f[x][y]=f[x][y]+dfs(x-1,dis(p,Y,x-1))/(double)m;    }    return f[x][y];}int main(){    scanf("%d %d",&n,&m);    for(int i=1;i<=m;i++) scanf("%d",&a[i]);    for(int i=1;i<=n;i++)        for(int j=0;j<n;j++) f[i][j]=-1;    for(int i=1;i<=n;i++) printf("%.2lf%%%c",dfs(n,i-1)*100.0,i!=n?' ':'\n');}
原创粉丝点击