1 2 0
1 1 2 7
设dp[i]为已经连续掷出i次相同点数,要到达目标状态所需的平均期望
则:dp[i] = (1/6)*(dp[i+1]+1) + (5/6)*(dp[1]+1)-----------------(1)
{ dp[0]是我们最终要求的值,dp[n] = 0 }
其中,下次掷出相同点数的概率为(1/6),再加上本身掷的一次,因此为(1/6)*(dp[i+1]+1)
如果下次掷的点数不同则相当于从1开始掷,因此为(5/6)*(dp[1]+1)
化简上式(1)可得:
dp[i] = (1/6)*(dp[i+1]) + (5/6)*(dp[1]) + 1------------------------(2)
dp[i+1] = (1/6)*(dp[i+2]) + (5/6)*(dp[1]) + 1---------------------(3)
两式相减(3) - (2)可得:
dp[i+1] - dp[i] = (1/6)*(dp[i+2] - dp[i+1])------------------------(4)
令a[i] = dp[i] - dp[i+1]-----------------------------------------------(5)
则a[i+1] = dp[i+2] - dp[i+1]
则(4)式变为:a[i+1] = 6*a[i]---------------------------------------(6)
由(2)式可知:dp[0] - dp[1] = 1,则a[0] = 1
因此a[i] = (1/6)^i------------------------------------------------------(7)
dp[n-1] - dp[n] = 6^(n-1)
dp[n-2] - dp[n-1] = 6^(n-2)
...
dp[0] - dp[1] = 1
则dp[0] = dp[n] + 6^0 + 6^1 + 6^2 + ... + 6^(n-2) + 6^(n-1)-----(8)
由于dp[n] = 0,则最终我们要求的结果dp[0]:
dp[0] = (6^n - 1)/5----------------------------------------------------(9)
即F[n] = (6^n - 1)/5--------------------------------------------------(10)
H[n] = 6*F[n] = 6*(6^n - 1)/5--------------------------------------(11)
G[m] = 6*m-----------------------------------------------------------(12)
由于题目要求使得G[m1]>=F[n] && G[m2]>=H[n]的最小整数值
则 m1 >= (6^n - 1)/30, m2>=(6^n - 1)/5
由于6^n尾数为6,因此要使得m1、m2为整数,则
m1 >= (6^n + 24)/30, m2>=(6^n - 1)/5
即求出在n的情况下上述两个表达式的值即可,
分母的情况用模n情况下的a的逆元来解决。
#include<stdio.h> #include<iostream> using namespace std; typedef long long LL; const LL MOD = 2011; LL quick_mod(LL a,LL b,LL m) { LL ans = 1; while(b) { if(b&1) { ans = (ans*a)%m; b--; } b/=2; a = a*a%m; } return ans; } int main() { //F(n) = (6^n-1)/5-----H(n) = 6*F(n)-----G(m) = 6*m; //M1 = (6^n+24)/30-----M2 = (6^n-1)/5 LL N; while(scanf("%I64d",&N) && N) { LL hehe,ans1,ans2; hehe = quick_mod(6,N,MOD); ans1 = ((hehe+24+MOD)%MOD*1944)%MOD; ans2 = ((hehe-1+MOD)%MOD*1609)%MOD; printf("%I64d %I64d\n",ans1,ans2); } return 0; }
原文地址:http://blog.csdn.net/demonstrate8/article/details/38510245