Topcoder SRM579 1000pts

Posted zhouyis

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 inline
il 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的主要内容,如果未能解决你的问题,请参考以下文章

TOPCODER SRM 686 div2 1000

TopCoder SRM502 Div1 1000 动态规划

Topcoder SRM 605 div1 题解

Topcoder SRM 608 div1 题解

Topcoder SRM 604 div1题解

topcoder srm 704 div1 -1000