Description
Given a normal dice (with 1, 2, 3, 4, 5, 6 on each face), we define:
F(N) to be the expected number of tosses until we have a number facing up for N consecutive times.
H(N) to be the expected number of tosses until we have the number '1' facing up for N consecutive times.
G(M) to be the expected number of tosses until we have the number '1' facing up for M times.
Given N, you are supposed to calculate the minimal M1 that G (M1) >= F (N) and the minimal M2 that G(M2)>=H(N)
F(N) to be the expected number of tosses until we have a number facing up for N consecutive times.
H(N) to be the expected number of tosses until we have the number '1' facing up for N consecutive times.
G(M) to be the expected number of tosses until we have the number '1' facing up for M times.
Given N, you are supposed to calculate the minimal M1 that G (M1) >= F (N) and the minimal M2 that G(M2)>=H(N)
Input
The input contains multiple cases.
Each case has a positive integer N in a separated line. (1<=N<=1000000000)
The input is terminated by a line containing a single 0.
Each case has a positive integer N in a separated line. (1<=N<=1000000000)
The input is terminated by a line containing a single 0.
Output
For each case, output the minimal M1 and M2 as required in a single line, separated by a single space.
Since the answer could be very large, you should output the answer mod 2011 instead.
Since the answer could be very large, you should output the answer mod 2011 instead.
Sample Input
1 2 0
Sample Output
1 1 2 7
思路:题意相当难理解,不过理解题意接下来就比较容易了。对于f[n]函数,令dp[i]表示剩余i次没抛出所期望要抛的点数。则有dp[i]=1/6*(dp[i-1]+1)+5/6*dp[n]。显然dp[0]=0.dp[n]即f[n]。经过求这个递推式的通项(相当麻烦的事情……)得到f[n]=(6^n-1)/5。另外,YY一下对于等概率的情况下,平均要抛6次才出现一次1,故h[n]=6*f[n]。
同理:g[m]=6*m。接下来就是求逆元的事情了。。。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
//Lint
#if defined (_WIN32) || defined (__WIN32) || defined (WIN32) || defined (__WIN32__)
#define LL __int64
#define LLS "%" "I" "6" "4" "d"
#else
#define LL long long
#define LLS "%" "l" "l" "d"
#endif
#define mod 2011
int exgcd(int a, int b, int &x, int &y) {
if (b == 0) {
x = 1;
y = 0;
return a;
}
int r = exgcd(b, a % b, y, x);
y -= x * (a / b);
return r;
}
int Inv(int a) {
int r, x, y;
r = exgcd(a, mod, x, y);
if (r == 1)
return (x % mod + mod) % mod;
return -1;
}
int quik(int n){
int base=6;
int sum=1;
while(n>0){
if(n&1)sum=(sum*base)%mod;
base=(base*base)%mod;
n>>=1;
}
return sum;
}
int main(int argc,char **argv){
int n;
int k1=Inv(30);
int k2=Inv(5);
while(~scanf("%d",&n)&&n){
n=n%(mod-1);
int pp=quik(n);
//cout<<pp<<endl;
int m1=(pp+24)%mod*k1%mod;
int m2=(pp-1)%mod*k2%mod;
printf("%d %d\n",m1,m2);
}
}