[bzoj2891]匹配难题
对于,定义表示左侧(对右侧前个点)存在完美匹配的集合为的概率
从转移到时枚举的出边,则
爆搜可得(当时)可能的仅有种,时间复杂度为
#include<bits/stdc++.h>
using namespace std;
#define N 105
#define M 40000
#define ull unsigned long long
int n,m,t;double ans,p[N][6],P[1<<6],g[M],f[M];
ull HSi[6],tr[M][1<<6];queue<ull>q;
map<ull,int>id;map<ull,int>::iterator it;
int main(){
scanf("%d%d",&n,&m);
if (n<=m){
for(int i=0;i<n;i++)
for(int j=1;j<=m;j++)scanf("%lf",&p[j][i]);
}
else{
swap(n,m);
for(int j=1;j<=m;j++)
for(int i=0;i<n;i++)scanf("%lf",&p[j][i]);
}
for(int i=0;i<n;i++)
for(int S=0;S<(1<<n);S++)
if ((S>>i)&1^1)HSi[i]|=((ull)1<<S);
t=id[1]=1,q.push(1);
while (!q.empty()){
ull HS=q.front();q.pop();
for(int S=0;S<(1<<n);S++){
ull HS0=HS;
for(int i=0;i<n;i++)
if ((S>>i)&1)HS0|=((HS&HSi[i])<<(1<<i));
if (!id[HS0])id[HS0]=++t,q.push(HS0);
tr[id[HS]][S]=id[HS0];
}
}
f[1]=1;
for(int i=1;i<=m;i++){
for(int S=0;S<(1<<n);S++){
P[S]=1;
for(int j=0;j<n;j++)P[S]*=((S>>j)&1 ? p[i][j] : 1-p[i][j]);
}
memcpy(g,f,sizeof(f));
memset(f,0,sizeof(f));
for(int HS=1;HS<=t;HS++)
for(int S=0;S<(1<<n);S++)f[tr[HS][S]]+=P[S]*g[HS];
}
for(it=id.begin();it!=id.end();it++){
int mx=0;
for(int S=0;S<(1<<n);S++)
if (((*it).first>>S)&1)mx=max(mx,__builtin_popcount(S));
ans+=mx*f[(*it).second];
}
printf("%.2f\n",ans);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
2020-06-14 [luogu3733]八纵八横