Codeforces 16E Fish 概率DP
这一场好水啊。。这题算是比較简单的概率DP了吧,外加一点状压。
dp[sta] = sigma (dp[sta|(1<<i)]*val[j][i]/( (ans+1)*ans/2 ) ),(i为sta已被吃掉的,j为存活的。ans为存活的个数)。
之所以要除( (ans+1)*ans/2 ),是由于在ans+1条鱼中一共同拥有这些对,且这些对等概率。
#include <algorithm> #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <queue> #include <cmath> #include <stack> #include <map> #include <ctime> #include <iomanip> #pragma comment(linker, "/STACK:1024000000"); #define EPS (1e-6) #define LL long long #define ULL unsigned long long #define _LL __int64 #define INF 0x3f3f3f3f #define Mod 1000000007 /** I/O Accelerator Interface .. **/ #define g (c=getchar()) #define d isdigit(g) #define p x=x*10+c-'0' #define n x=x*10+'0'-c #define pp l/=10,p #define nn l/=10,n template<class T> inline T& RD(T &x) { char c; while(!d); x=c-'0'; while(d)p; return x; } template<class T> inline T& RDD(T &x) { char c; while(g,c!='-'&&!isdigit(c)); if (c=='-') { x='0'-g; while(d)n; } else { x=c-'0'; while(d)p; } return x; } inline double& RF(double &x) //scanf("%lf", &x); { char c; while(g,c!='-'&&c!='.'&&!isdigit(c)); if(c=='-')if(g=='.') { x=0; double l=1; while(d)nn; x*=l; } else { x='0'-c; while(d)n; if(c=='.') { double l=1; while(d)nn; x*=l; } } else if(c=='.') { x=0; double l=1; while(d)pp; x*=l; } else { x=c-'0'; while(d)p; if(c=='.') { double l=1; while(d)pp; x*=l; } } return x; } #undef nn #undef pp #undef n #undef p #undef d #undef g using namespace std; double val[20][20]; double dp[1<<18]; bool vis[20]; double dfs(int sta,int n,int ans) { if(dp[sta] > -0.5) return dp[sta]; dp[sta] = 0; int i,j; double tmp; for(i = 0;i < n; ++i) { if(vis[i] == false) { vis[i] = true; tmp = dfs(sta|(1<<i),n,ans+1); vis[i] = false; for(j = 0;j < n; ++j) if(vis[j]) dp[sta] += tmp*val[j][i]/((ans+1)*ans/2.0); } } return dp[sta]; } int main() { int n,i,j; scanf("%d",&n); for(i = 0;i < n; ++i) for(j = 0;j < n; ++j) scanf("%lf",&val[i][j]); memset(dp,-1,sizeof(dp)); dp[(1<<n)-1] = 1; memset(vis,false,sizeof(vis)); for(i = 0;i < n; ++i) { vis[i] = true; dp[1<<i] = dfs(1<<i,n,1); vis[i] = false; } for(i = 0;i < n; ++i) printf("%.10lf ",dp[1<<i]); return 0; }