CF16E Fish (状压dp)

数据范围是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;
}
View Code

 

posted @ 2020-09-26 21:54  朝暮不思  阅读(139)  评论(0)    收藏  举报