题解:CF1773G Game of Questions
CF1773G Game of Questions
体现了一种【不合法情况一定不产生影响】的思想。注意到人数
按常规套路,把这个转移解成递推式:
但这样是否正确?注意到题目中的问题是以排列的形式呈现的,问过的问题不能再被拿出来用,所以看似我们的
还需要求出
:::info[代码]
#include <bits/stdc++.h>
#define psb push_back
#define db long double
using namespace std;
typedef pair<int,int> PII;
#define fir first
#define sec second
const int N=17;
int m,n;
vector<PII> trans[1<<N];
inline int lowbit(int x) { return x & (-x); }
int buc[1<<N];
db f[1<<N];
int main()
{
cin >> m >> n;
int U=(1<<n)-1;
for (int S=0;S<=U;S++)
{
for (int T=S;;T=(T-1)&S)
{
trans[S].psb({T,0});
if (!T) break;
}
reverse(trans[S].begin(),trans[S].end());
}
for (int i=1;i<=m;i++)
{
string str; cin >> str;
int S=0; for (int j=0;j<n;j++) if (str[j]=='1') S|=(1<<j);
trans[U][S].sec++;
}
for (int S=U-1;~S;S--)
{
int x=lowbit(U^S);
for (auto [T,w] : trans[S|x]) buc[T]=w;
for (auto &p : trans[S])
{
int T=p.fir,w=p.sec;
p.sec=buc[T]+buc[T|x];
}
for (auto [T,w] : trans[S|x]) buc[T]=0;
}
for (int S=1;S<=U;S++)
{
if (!(S&1)) continue;
int tot=m-trans[S][0].sec-trans[S].back().sec;
if (!tot) { f[S]=1; continue; }
db sum=0; for (auto [T,w] : trans[S]) sum+=f[T]*w;
f[S]=sum/tot;
}
printf("%.12Lf",f[U]);
return 0;
}
:::