题意:
N只FISH。每个回合会有一只FISH吃掉另一个FISH。直到池塘里只剩一只FISH。
给出aij:第i只FISH吃掉第J只FISH的概率。
问每一只FISH是最后存活者的概率。
Input
The first line contains integer n (1 ≤ n ≤ 18) — the amount of fish in the lake. Then there follow n lines with n real numbers each — matrix a. aij (0 ≤ aij ≤ 1) — the probability that fish with index i eats up fish with index j. It‘s guaranteed that the main diagonal contains zeros only, and for other elements the following is true: aij = 1 - aji. All real numbers are given with not more than 6 characters after the decimal point.
思路:
仔细想想是个DP。N很小,状压DP。。。。
DP方程要推对。【*:写完方程试一两个SAMPLE】
看代码
代码:
int n; double a[20][20]; double dp[(1<<18)+5]; int STATE[20][(1<<18)+5]; int STATE_n[20]; int calc(int x){ int res=0; rep(i,0,n-1){ if((x&(1<<i))!=0){ ++res; } } ret res; } void makeState(){ mem(STATE_n,0); int tot=((1<<n)-1); rep(i,1,tot){ int t=calc(i); STATE[t][++STATE_n[t]]=i; } } int main(){ cin>>n; rep(i,0,n-1) rep(j,0,n-1) scanf("%lf",&a[i][j]); mem(dp,0); dp[(1<<n)-1]=1.0; makeState(); rep2(k,n-1,1){ int s=-1, _s=-1; rep(i,1,STATE_n[k]){ //枚举nowState s=STATE[k][i]; rep(j,0,n-1){ if((s&(1<<j))==0){ _s=s|(1<<j); rep(t,0,n-1){ if((s&(1<<t))!=0){ dp[s]+=(2*dp[_s]*a[t][j]/(k*(k+1))); } } } } } } printf("%lf",dp[1]); rep(i,1,n-1){ printf(" %lf",dp[1<<i]); } cout<<endl; ret 0; }
时间: 2024-10-29 04:34:46