首页 > 代码库 > Topcoder SRM579 1000pts

Topcoder SRM579 1000pts

石头剪刀布QAQ

一看是个很油的概率dp

首先一看你很快能得出状态的表示F[i][r][p][s]

然后只要考虑r,p,s出现的次数来进行概率dp就好了

具体实现的时候细节很多(少)

如果预处理一下组合数常数短了一截。但是自信的我认为50^4根本不慌。最后还是过了。

#include<map>#include<stack>#include<queue>#include<cstdio>#include<string>#include<vector>#include<cstring>#include<complex>#include<iostream>#include<assert.h>#include<algorithm>using namespace std;#define inf 1001001001#define infll 1001001001001001001LL#define ll long long#define dbg(vari) cerr<<#vari<<" = "<<(vari)<<endl#define gmax(a,b) (a)=max((a),(b))#define gmin(a,b) (a)=min((a),(b))#define Ri register int#define gc getchar()#define il inlineil int read(){    bool f=true;Ri x=0;char ch;while(!isdigit(ch=gc))if(ch==-)f=false;while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-0;ch=gc;}return f?x:-x;}#define gi read()#define ig read()#define FO(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout);int n;double ans,R[55],P[55],S[55];double dp[55][55][55][55];int main(){    FO(rps);    n=gi;    for(int i=0;i<n;i++){        R[i]=gi;R[i]/=300;        P[i]=gi;P[i]/=300;        S[i]=gi;S[i]/=300;    }    for(int a=0;a<n;a++){        dp[a][0][0][0]=1.0;        for(int i=0;i<n;i++)            for(int j=i;j+1;j--)                for(int k=i-j;k+1;k--)                    for(int s=i-j-k;s+1;s--) {                        if(i!=a){                        dp[a][j+1][k][s]=dp[a][j+1][k][s]+1.0*(j+k+s+1)/(i+1)*R[i]*dp[a][j][k][s];                        dp[a][j][k+1][s]=dp[a][j][k+1][s]+1.0*(j+k+s+1)/(i+1)*P[i]*dp[a][j][k][s];                        dp[a][j][k][s+1]=dp[a][j][k][s+1]+1.0*(j+k+s+1)/(i+1)*S[i]*dp[a][j][k][s];                                }dp[a][j][k][s]=dp[a][j][k][s]*(1-1.0*(j+k+s)/(i+1));                            }        }    for(int i=0;i<n;i++){        for(int j=0;j<n-i;j++){            for(int k=0;k<n-i-j;k++){                double r,p,s;                r=p=s=0;                //face i rock k scissor j paper                for(int a=0;a<n;a++){                    double t=dp[a][i][j][k],m=n-i-j-k;                    r=r+dp[a][i][j][k]/m*R[a];                    p=p+dp[a][i][j][k]/m*P[a];                    s=s+dp[a][i][j][k]/m*S[a];                }                double tmp=0.0;                gmax(tmp,3*r+p);                gmax(tmp,3*p+s);                gmax(tmp,3*s+r);                /*                old version fucking possiblities                gmax(ans,3*r+p);                gmax(ans,3*p+s);                gmax(ans,3*s+r);*/                ans+=tmp;                    }        }    }    printf("%.9lf",ans);    return 0;}

Topcoder SRM579 1000pts