数据范围是18,因此考虑使用状压dp表示状态
对于每个状态,可以是由很多种状态转移而来的,我们考虑i吃j的情况,更新所有状态
因为每次状态的减少都是因为一队鱼相遇产生。
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=4e5+10; typedef long long ll; double a[110][110]; double f[N]; int main(){ ios::sync_with_stdio(false); int n; cin>>n; int i,j; for(i=1;i<=n;i++){ for(j=1;j<=n;j++) cin>>a[i][j]; } int k; f[(1<<n)-1]=1; for(int s=(1<<n)-1;s>=1;s--){ int num=0; for(i=0;i<n;i++){ if(s>>i&1) num++; } if(num==1) continue; double sign=2.0/num/(num-1.0); for(i=0;i<n;i++){ if(!(s>>i&1)) continue; int tmp=s-(1<<i); for(j=0;j<n;j++){ if(i!=j&&s>>j&1){ f[tmp]+=f[s]*sign*a[j+1][i+1];//枚举出所有可能产生这种情况的答案,所以是加法 } } } } for(i=0;i<n;i++){ printf("%.6f ",f[1<<i]); } cout<<endl; }