BSOJ8163题解

看到值域很小而且时限 4s 以为是什么高明的依赖值域的复杂度,结果就是优化 DP。

考场上只想到了 \(O(n^5)\) 的还是太菜了。

\(dp[l][r][x]\) 表示 \([l,r]\) 这个区间中 \(x\) 赢得最终胜利的概率。容易有 \(O(n^5)\) 转移。

但是很显然 \(x\) 左边的人不可能与右边的人对战,所以 \([l,x]\)\([x,r]\) 这两个区间是完全独立的。

也就是说 \(dp[l][r][x]=F[l][x]\times G[x][r]\)\(F[l][r]\) 表示 \([l,r]\) 这个区间中 \(r\) 取得了最终的胜利,\(G[l][r]\) 定义相反。

转移:

\[F[l][r]=\frac{1}{r-l}\sum_{k=l}^{r-1}\sum_{x=l}^{k}F[l][x]\times G[x][k]\times\frac{a_r}{a_x+a_r}\times F[k+1][r] \]

\(G\) 类似。

\(f[l][r]=\sum_{i=l}^{r}G[l][i]\times F[i+1][r]\),那么有:

\[F[l][r]=\frac{1}{r-l}\sum_{x=l}^{r-1}F[l][x]\times f[x][r]\times\frac{a_r}{a_x+a_r} \]

没了。复杂度 \(O(n^3)\)。注意边界。

#include<cstdio>
#include<cctype>
namespace SOLVE{
	typedef double db;
	const int M=505;
	int n,k,a[M];db F[M][M],G[M][M],H[M][M];
	inline void main(){
		scanf("%d%d",&n,&k);for(int i=1;i<=n;++i)scanf("%d",a+i),F[i][i]=G[i][i]=1;
		for(int t=2;t<=n;++t){
			for(int l=1,r=t;r<=n;++l,++r){
				for(int i=l;i<r;++i)H[l][r]+=G[l][i]*F[i+1][r];
				for(int i=l;i<r;++i)F[l][r]+=1.*a[r]/(a[i]+a[r])*F[l][i]*H[i][r];
				for(int i=r;i>l;--i)G[l][r]+=1.*a[l]/(a[i]+a[l])*H[l][i]*G[i][r];
				F[l][r]/=r-l;G[l][r]/=r-l;
			}
		}
		printf("%.10lf",F[1][k]*G[k][n]);
	}
}
signed main(){
	SOLVE::main();
}
posted @ 2022-09-26 14:57  Prean  阅读(59)  评论(1编辑  收藏  举报
var canShowAdsense=function(){return !!0};