题目大意:
又是一个游戏。这个游戏有两方
A,B
,
A
方问问题,
分析:
就是一个裸的状压概率
dp
,
fs,i,j
表示选了的状态为
s
,双方积分为
AC code:
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
#include <string>
#include <sstream>
#include <iostream>
#include <map>
#include <set>
#include <list>
#include <stack>
#include <queue>
#include <vector>
#define pb push_back
#define mp make_pair
#define get(x, i) (((x)>>(i-1))&1)
typedef long long LL;
typedef double DB;
typedef long double LD;
using namespace std;
int n;
DB p[14], sum;
DB f[7][7][1<<13];
DB tp[1<<13][14];
DB ans[7][7];
int main()
{
#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
#endif
cin >> n;
for(int i = 1; i <= 12; ++i)
cin >> p[i];
DB x, sum = 0;
for(int i = 1; i <= n; ++i)
cin >> x, sum += x;
p[13] = sum/n;
for(int i = 0; i < (1<<13)-1; ++i)
{
int now = 1, s, cnt = 0;
while(get(i, now)) now++;
s = now, now = now%13+1;
while(true)
{
cnt = 1;
while(get(i, now)) now = now%13+1, cnt++;
tp[i][now] = 1.0*cnt/13;
if(now == s) break;
now = now%13+1;
}
}
f[0][0][0] = 1;
for(int i = 0; i <= 6; ++i)
for(int j = 0; j <= 6; ++j)
if(i != 6 && j != 6)
for(int s = 0; s < (1<<13); ++s)
if(f[i][j][s] > 0)
for(int l = 1; l <= 13; ++l)
if(!get(s, l))
{
f[i+1][j][s|(1<<(l-1))] += f[i][j][s]*tp[s][l]*p[l];
f[i][j+1][s|(1<<(l-1))] += f[i][j][s]*tp[s][l]*(1-p[l]);
}
for(int i = 0; i <= 6; ++i)
for(int j = 0; j <= 6; ++j)
for(int s = 0; s < (1<<13); ++s)
ans[i][j] += f[i][j][s];
for(int i = 0; i <= 5; ++i)
printf("%.3lf\n", ans[6][i]);
for(int i = 5; i >= 0; --i)
printf("%.3lf\n", ans[i][6]);
#ifndef ONLINE_JUDGE
fclose(stdin);
fclose(stdout);
#endif
return 0;
}