概率dp初步

CF16E Fish

状压dp记录每只小鱼的生死状态,每个状态枚举被吃的小鱼和吃他的小鱼转移过来,吃有个概率,恰好是这两只小鱼互吃也有个概率。

#include<bits/stdc++.h>
// #define ll long long
// #define int ll
#define ls t[p].l
#define rs t[p].r
#define re register 
#define pb push_back
#define pir pair<int,int> 
#define f(a,x,i) for(int i=a;i<=x;i++)
#define fr(a,x,i) for(int i=a;i>=x;i--)
#define lowbit(x) x&-x;
using namespace std;
const int N=23;
const int M=1e6+4;
const int mod=998244353;
const int INF=0x3f3f3f3f3f3f3f3fLL;

int n;
double a[N][N];
double f[1<<20];

void solve(){
    cin>>n;

    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            cin>>a[i][j];
        }
    }
    int s=(1<<n)-1;
    f[s]=1;
    for(int i=s-1;i>=0;i--){
        int cnt=__builtin_popcount(i);
        for(int j=1;j<=n;j++){//death
            if(i&(1<<(j-1))) continue;
            for(int k=1;k<=n;k++){//eat
                if(!(i&(1<<(k-1)))) continue;
                f[i]+=f[i|(1<<(j-1))]*a[k][j]/(1.0*(cnt+1)*cnt/2.0);
            }
        }
    }

    for(int i=1;i<=n;i++){
        cout<<fixed<<setprecision(6);
        cout<<f[1<<(i-1)]<<" ";
    }
}
signed main(){
	// freopen("a.in","r",stdin);
	// freopen("a.out","w",stdout);
    ios::sync_with_stdio(0);
    cin.tie(nullptr);   
    int t=1;
    // cin>>t;
    while(t--){
        solve();
    }
    return 0;
}
posted @ 2025-05-03 14:35  sad_lin  阅读(8)  评论(0)    收藏  举报