LightOJ 1038 Race to 1 Again (簡單期望)

issue敲膩害發表於2020-10-20

hhhh傳送門

一個數的因子有 n u m num num個,分別是 a 1 , a 2 . . , a n u m a_1,a_2..,a_{num} a1,a2..,anum

定義 d p [ i ] dp[i] dp[i] i i i轉換為 1 1 1的期望次數

d p [ i ] = d p [ a 1 ] + d p [ a 2 ] . . . + d p [ n u m ] n u m + 1 dp[i]=\frac{dp[a_1]+dp[a_2]...+dp[num]}{num}+1 dp[i]=numdp[a1]+dp[a2]...+dp[num]+1

其中 d p [ n u m ] = d p [ i ] ( i = = n u m ) dp[num]=dp[i](i==num) dp[num]=dp[i](i==num)

所以移項可解得 d p [ i ] dp[i] dp[i]

#include <bits/stdc++.h>
using namespace std;
const int maxn=2e5+10;
int t,n,a[maxn],num[maxn];
double dp[maxn];
void print()
{
	for(int i=1;i<=100000;i++)
	for(int j=i;j<=100000;j+=i)
		num[j]++;
}
int main()
{
	print();
	cin >> t; int casenum=0;
	while( t-- )
	{
		int top = 0;
		cin >> n;
		for(int i=1;i<=n/2;i++)
			if( n%i==0 )	a[++top]=i;
		a[++top] = n;
		for(int i=2;i<=top;i++)
		{
			for(int j=1;j<i;j++)
			{
				if( a[i]%a[j]!=0 )	continue;
				dp[i] +=	( dp[j]+1 )/num[ a[i] ];
			}
			if( num[ a[i] ]==1 )	continue;
			double x = 1.0/num[a[i]];
			dp[i] = ( dp[i]+x )/(1-x);
		}
		printf("Case %d: %.7lf\n",++casenum,dp[top] );
		for(int i=1;i<=top;i++)	dp[i]=0;
	}
}

相關文章