HDU4652 Dice

这个题的正解是 (O(n)) 一次询问的, 主要用到的技巧是数列操作的技巧。

type 0

使用期望 dp, 设 f[i] 表示末尾已有 i 个相同的, 停止所需的期望次数, 所求即为 f[0]。

[egin{align} f[0] &= 1 +f[1] ag{1} \ f[i] &= 1 + frac 1mf[i+1] + frac{m-1}{m}f[1] ag{2} \ f[i+1] &= 1 + frac 1mf[i+2] + frac{m-1}{m}f[1] ag{3} \ f[n] &= 0 ag{4} end{align} ]

((2)-(3)) 得:

[m*(f[i]-f[i+1]) =f[i+1]-f[i+2] ]

注意到这是个递推式, 设 (f'[i] = f[i]-f[i+1]), 那么 (f[0] = sumlimits_{i=0}^{n-1} f'[i])(由于 (f[n]=0))。

显然 (f'[0]=1),于是就可以递推了。

type 1

还是使用期望 dp, 设 f[i] 表示末尾已有 i 个两两不同的, 停止所需的期望次数, 所求还是 f[0]。

[egin{align} f[0] &= 1+f[1] ag{1} \ f[i] &= 1 + frac{m-i}{m} f[i+1] + frac 1m left( f[1]+f[2]+cdots +f[i] ight) ag{2} \ f[i+1] &= 1 + frac{m-i-1}{m} f[i+2] + frac 1m left( f[1]+f[2]+cdots +f[i+1] ight) ag{3} \ f[n] &= 0 ag{4} end{align} ]

还是 ((2)-(3)) 得:

[egin{align} f[i] - f[i+1] &= frac{m-i}mf[i+1] - frac{m-i-1}mf[i+2] - frac 1mf[i+1] \ m*f[i] - m*f[i+1] &= (m-i)*f[i+1] - (m-i-1)*f[i+2] - f[i+1] \ m*f[i] - m*f[i+1] &= (m-i-1)*f[i+1] - (m-i-1)*f[i+2] \ m*(f[i]-f[i+1]) &= (m-i-1)*(f[i+1]-f[i+2]) end{align} ]

又是个递推式, 设 (f'[i] = f[i]-f[i+1]), 依然有 (f[0] = sumlimits_{i=0}^{n-1} f'[i])

显然 (f[0]=1), 依然可以递推。

code

hduOJ 厌 getchar type 快读好震撼啊。

#include<cstdio>
#define gc() getchar()
using namespace std;

double calc0(int n,int m)
{
	double res = 1,  f = 1;
	for(int i=1;i<n;++i)
	{
		f = f * m;
		res += f;
	}
	return res;
}

double calc1(int n,int m)
{
	double res = 1,  f = 1;
	for(int i=1;i<n;++i)
	{
		f = f * m / (m-i);
		res += f;
	}
	return res;
}

int main()
{
//	cout << calc0(5,6);
	int T;
	scanf("%d",&T);
	while(T--)
	{
		int op,n,m;
		scanf("%d%d%d",&op,&m,&n);
		if(op==0)
			printf("%.9lf
", calc0(n,m));
		else
			printf("%.9lf
", calc1(n,m));		
	}
	return 0;
}
原文地址:https://www.cnblogs.com/tztqwq/p/14053221.html