每一轮的策略跟之前出现过的剪刀石头布的数量有关
另 fi,a,b,c f i , a , b , c 表示之前出现了 a a 次石头, b b 次剪刀 , c c 次布,然后第 i i 个筛子没用过的概率
DP一下,每一轮独立算贡献
// BEGIN CUT HERE
// END CUT HERE
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define pb push_back
#define fi first
#define se second
using namespace std;
const int N=51;
int n;
double a[N],b[N],c[N],f[N][N][N][N],C[N][N];
class RockPaperScissors{
public:
double bestScore(vector <int> Aa, vector <int> Bb, vector <int> Cc) {
n=Aa.size();
for(int i=1;i<=n;i++) a[i]=Aa[i-1];
for(int i=1;i<=n;i++) b[i]=Bb[i-1];
for(int i=1;i<=n;i++) c[i]=Cc[i-1];
for(int i=0;i<=n;i++){
C[i][0]=1;
for(int j=1;j<=i;j++)
C[i][j]=C[i-1][j]+C[i-1][j-1];
}
memset(f,0,sizeof(f));
double ans=0;
for(int i=1;i<=n;i++){
f[i][0][0][0]=1;
for(int j=1;j<=n;j++){
if(j==i) continue;
for(int t=j;t;t--){
for(int x=0;x<=t;x++)
for(int y=0;x+y<=t;y++){
int z=t-x-y;
if(x) f[i][x][y][z]+=f[i][x-1][y][z]*a[j]/300;
if(y) f[i][x][y][z]+=f[i][x][y-1][z]*b[j]/300;
if(z) f[i][x][y][z]+=f[i][x][y][z-1]*c[j]/300;
}
}
}
for(int x=0;x<=n-1;x++)
for(int y=0;x+y<=n-1;y++)
for(int z=0;x+y+z<=n-1;z++)
f[i][x][y][z]/=C[n][x+y+z];
}
for(int x=0;x<=n-1;x++)
for(int y=0;x+y<=n-1;y++)
for(int z=0;x+y+z<=n-1;z++){
int r=n-x-y-z;
double pa=0,pb=0,pc=0;
for(int i=1;i<=n;i++){
pa+=f[i][x][y][z]*a[i]/300;
pb+=f[i][x][y][z]*b[i]/300;
pc+=f[i][x][y][z]*c[i]/300;
}
pa/=r; pb/=r; pc/=r;
ans+=max(3*pa+pb,max(3*pb+pc,3*pc+pa));
}
return ans;
}
// BEGIN CUT HERE
public:
void run_test(int Case) { if ((Case == -1) || (Case == 0)) test_case_0(); if ((Case == -1) || (Case == 1)) test_case_1(); if ((Case == -1) || (Case == 2)) test_case_2(); if ((Case == -1) || (Case == 3)) test_case_3(); if ((Case == -1) || (Case == 4)) test_case_4(); }
private:
template <typename T> string print_array(const vector &V) { ostringstream os; os << "{ "; for (typename vector ::const_iterator iter = V.begin(); iter != V.end(); ++iter) os << '\"' << *iter << "\","; os << " }"; return os.str(); }
void verify_case(int Case, const double &Expected, const double &Received) { cerr << "Test Case #" << Case << "..."; if (Expected == Received) cerr << "PASSED" << endl; else { cerr << "FAILED" << endl; cerr << "\tExpected: \"" << Expected << '\"' << endl; cerr << "\tReceived: \"" << Received << '\"' << endl; } }
void test_case_0() { int Arr0[] = {100, 100, 100}; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arr1[] = {100, 100, 100}; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); int Arr2[] = {100, 100, 100}; vector <int> Arg2(Arr2, Arr2 + (sizeof(Arr2) / sizeof(Arr2[0]))); double Arg3 = 3.999999999999999; verify_case(0, Arg3, bestScore(Arg0, Arg1, Arg2)); }
void test_case_1() { int Arr0[] = {300}; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arr1[] = {0}; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); int Arr2[] = {0}; vector <int> Arg2(Arr2, Arr2 + (sizeof(Arr2) / sizeof(Arr2[0]))); double Arg3 = 3.0; verify_case(1, Arg3, bestScore(Arg0, Arg1, Arg2)); }
void test_case_2() { int Arr0[] = {300, 0, 0}; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arr1[] = {0, 300, 0}; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); int Arr2[] = {0, 0, 300}; vector <int> Arg2(Arr2, Arr2 + (sizeof(Arr2) / sizeof(Arr2[0]))); double Arg3 = 6.333333333333332; verify_case(2, Arg3, bestScore(Arg0, Arg1, Arg2)); }
void test_case_3() { int Arr0[] = {100, 0}; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arr1[] = {200, 100}; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); int Arr2[] = {0, 200}; vector <int> Arg2(Arr2, Arr2 + (sizeof(Arr2) / sizeof(Arr2[0]))); double Arg3 = 3.7222222222222223; verify_case(3, Arg3, bestScore(Arg0, Arg1, Arg2)); }
void test_case_4() { int Arr0[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
,0,0,0,0,0,0,0,0,0}; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arr1[] = {150,300,300,300,300,300,300,300,300,300,300,300,300,300
,300,300,300,300,300,300,300,300,300,300,300,300,300,300
,300,300,300,300,300,300,300,300,300,300,300,300,300,300
,300,300,300,300,300,300,300,300}; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); int Arr2[] = {150,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
,0,0,0,0,0,0,0,0,0}; vector <int> Arg2(Arr2, Arr2 + (sizeof(Arr2) / sizeof(Arr2[0]))); double Arg3 = 149.00000000000003; verify_case(4, Arg3, bestScore(Arg0, Arg1, Arg2)); }
// END CUT HERE
};
// BEGIN CUT HERE
int main()
{
RockPaperScissors ___test;
___test.run_test(-1);
system("pause");
}
// END CUT HERE