给定长度为N的从1到N的线性板,任务是找到到达板的第N个单元所需的预期移动数,如果我们从编号为1的单元开始,并且每一步都滚动一个立方骰子决定下一步行动。而且,我们不能走出董事会的界限。请注意,预期的移动次数可以是分数。
例子:
Input: N = 8
Output: 7
p1 = (1 / 6) | 1-step -> 6 moves expected to reach the end
p2 = (1 / 6) | 2-steps -> 6 moves expected to reach the end
p3 = (1 / 6) | 3-steps -> 6 moves expected to reach the end
p4 = (1 / 6) | 4-steps -> 6 moves expected to reach the end
p5 = (1 / 6) | 5-steps -> 6 moves expected to reach the end
p6 = (1 / 6) | 6-steps -> 6 moves expected to reach the end
If we are 7 steps away, then we can end up at 1, 2, 3, 4, 5, 6 steps
away with equal probability i.e. (1 / 6).
Look at the above simulation to understand better.
dp[N – 1] = dp[7]
= 1 + (dp[1] + dp[2] + dp[3] + dp[4] + dp[5] + dp[6]) / 6
= 1 + 6 = 7
Input: N = 10
Output: 7.36111
方法:在较早的文章中已经讨论了基于动态编程的方法。在本文中,将讨论一种更优化的方法来解决此问题。这个想法是使用一种称为矩阵求幂的技术。
让我们将A n定义为到达长度为N +1的木板末端的预期移动次数。
重复关系将是:
An = 1 + (An-1 + An-2 + An-3 + An-4 + An-5 + An-6) / 6
现在,递归关系需要以合适的格式转换。
An = 1 + (An-1 + An-2 + An-3 + An-4 + An-5 + An-6) / 6 (equation 1)
An-1 = 1 + (An-2 + An-3 + An-4 + An-5 + An-6 + An-7) / 6 (equation 2)
Substracting 1 with 2, we get An = 7 * (An-1) / 6 – (An-7) / 6
矩阵求幂技术可以在上面的递归关系上应用。
底数为{6,6,6,6,6,6,0 },对应于{A6,A5,A4…,A0}
乘数将是
{
{7/6, 1, 0, 0, 0, 0, 0},
{0, 0, 1, 0, 0, 0, 0},
{0, 0, 0, 1, 0, 0, 0},
{0, 0, 0, 0, 1, 0, 0},
{0, 0, 0, 0, 0, 1, 0},
{0, 0, 0, 0, 0, 0, 1},
{-1/6, 0, 0, 0, 0, 0, 0}
}
查找值:
- 查找mul (N – 7)
- 找到基数* mul (N – 7) 。
- 1 * 7矩阵的第一个值将是必需的答案。
下面是上述方法的实现:
C++
// C++ implementation of the approach
#include
#define maxSize 50
using namespace std;
// Function to multiply two 7 * 7 matrix
vector > matrix_product(
vector > a,
vector > b)
{
vector > c(7);
for (int i = 0; i < 7; i++)
c[i].resize(7, 0);
for (int i = 0; i < 7; i++)
for (int j = 0; j < 7; j++)
for (int k = 0; k < 7; k++)
c[i][j] += a[i][k] * b[k][j];
return c;
}
// Function to perform matrix exponentiation
vector > mul_expo(vector > mul, int p)
{
// 7 * 7 identity matrix
vector > s = { { 1, 0, 0, 0, 0, 0, 0 },
{ 0, 1, 0, 0, 0, 0, 0 },
{ 0, 0, 1, 0, 0, 0, 0 },
{ 0, 0, 0, 1, 0, 0, 0 },
{ 0, 0, 0, 0, 1, 0, 0 },
{ 0, 0, 0, 0, 0, 1, 0 },
{ 0, 0, 0, 0, 0, 0, 1 } };
// Loop to find the power
while (p != 1) {
if (p % 2 == 1)
s = matrix_product(s, mul);
mul = matrix_product(mul, mul);
p /= 2;
}
return matrix_product(mul, s);
}
// Function to return the required count
double expectedSteps(int x)
{
// Base cases
if (x == 0)
return 0;
if (x <= 6)
return 6;
// Multiplier matrix
vector > mul = { { (double)7 / 6, 1, 0, 0, 0, 0, 0 },
{ 0, 0, 1, 0, 0, 0, 0 },
{ 0, 0, 0, 1, 0, 0, 0 },
{ 0, 0, 0, 0, 1, 0, 0 },
{ 0, 0, 0, 0, 0, 1, 0 },
{ 0, 0, 0, 0, 0, 0, 1 },
{ (double)-1 / 6, 0, 0, 0, 0, 0, 0 } };
// Finding the required multiplier
// i.e mul^(X-6)
mul = mul_expo(mul, x - 6);
// Final answer
return (mul[0][0]
+ mul[1][0]
+ mul[2][0]
+ mul[3][0]
+ mul[4][0]
+ mul[5][0])
* 6;
}
// Driver code
int main()
{
int n = 10;
cout << expectedSteps(n - 1);
return 0;
}
Java
// Java implementation of the approach
class GFG
{
static final int maxSize = 50;
// Function to multiply two 7 * 7 matrix
static double [][] matrix_product(double [][] a,
double [][] b)
{
double [][] c = new double[7][7];
for (int i = 0; i < 7; i++)
for (int j = 0; j < 7; j++)
for (int k = 0; k < 7; k++)
c[i][j] += a[i][k] * b[k][j];
return c;
}
// Function to perform matrix exponentiation
static double [][] mul_expo(double [][] mul, int p)
{
// 7 * 7 identity matrix
double [][] s = {{ 1, 0, 0, 0, 0, 0, 0 },
{ 0, 1, 0, 0, 0, 0, 0 },
{ 0, 0, 1, 0, 0, 0, 0 },
{ 0, 0, 0, 1, 0, 0, 0 },
{ 0, 0, 0, 0, 1, 0, 0 },
{ 0, 0, 0, 0, 0, 1, 0 },
{ 0, 0, 0, 0, 0, 0, 1 }};
// Loop to find the power
while (p != 1)
{
if (p % 2 == 1)
s = matrix_product(s, mul);
mul = matrix_product(mul, mul);
p /= 2;
}
return matrix_product(mul, s);
}
// Function to return the required count
static double expectedSteps(int x)
{
// Base cases
if (x == 0)
return 0;
if (x <= 6)
return 6;
// Multiplier matrix
double [][]mul = { { (double)7 / 6, 1, 0, 0, 0, 0, 0 },
{ 0, 0, 1, 0, 0, 0, 0 },
{ 0, 0, 0, 1, 0, 0, 0 },
{ 0, 0, 0, 0, 1, 0, 0 },
{ 0, 0, 0, 0, 0, 1, 0 },
{ 0, 0, 0, 0, 0, 0, 1 },
{(double) - 1 / 6, 0, 0,
0, 0, 0, 0 }};
// Finding the required multiplier
// i.e mul^(X-6)
mul = mul_expo(mul, x - 6);
// Final answer
return (mul[0][0] + mul[1][0] + mul[2][0] +
mul[3][0] + mul[4][0] + mul[5][0]) * 6;
}
// Driver code
public static void main(String[] args)
{
int n = 10;
System.out.printf("%.5f",expectedSteps(n - 1));
}
}
// This code is contributed by PrinciRaj1992
Python3
# Python3 implementation of the approach
import numpy as np
maxSize = 50
# Function to multiply two 7 * 7 matrix
def matrix_product(a, b) :
c = np.zeros((7, 7));
for i in range(7) :
for j in range(7) :
for k in range(7) :
c[i][j] += a[i][k] * b[k][j];
return c
# Function to perform matrix exponentiation
def mul_expo(mul, p) :
# 7 * 7 identity matrix
s = [ [ 1, 0, 0, 0, 0, 0, 0 ],
[ 0, 1, 0, 0, 0, 0, 0 ],
[ 0, 0, 1, 0, 0, 0, 0 ],
[ 0, 0, 0, 1, 0, 0, 0 ],
[ 0, 0, 0, 0, 1, 0, 0 ],
[ 0, 0, 0, 0, 0, 1, 0 ],
[ 0, 0, 0, 0, 0, 0, 1 ] ];
# Loop to find the power
while (p != 1) :
if (p % 2 == 1) :
s = matrix_product(s, mul);
mul = matrix_product(mul, mul);
p //= 2;
return matrix_product(mul, s);
# Function to return the required count
def expectedSteps(x) :
# Base cases
if (x == 0) :
return 0;
if (x <= 6) :
return 6;
# Multiplier matrix
mul = [ [ 7 / 6, 1, 0, 0, 0, 0, 0 ],
[ 0, 0, 1, 0, 0, 0, 0 ],
[ 0, 0, 0, 1, 0, 0, 0 ],
[ 0, 0, 0, 0, 1, 0, 0 ],
[ 0, 0, 0, 0, 0, 1, 0 ],
[ 0, 0, 0, 0, 0, 0, 1 ],
[ -1 / 6, 0, 0, 0, 0, 0, 0 ] ];
# Finding the required multiplier
# i.e mul^(X-6)
mul = mul_expo(mul, x - 6);
# Final answer
return (mul[0][0] + mul[1][0] + mul[2][0] +
mul[3][0] + mul[4][0] + mul[5][0]) * 6;
# Driver code
if __name__ == "__main__" :
n = 10;
print(expectedSteps(n - 1));
# This code is contributed by AnkitRai01
C#
// C# implementation of the approach
using System;
class GFG
{
static readonly int maxSize = 50;
// Function to multiply two 7 * 7 matrix
static double [,] matrix_product(double [,] a,
double [,] b)
{
double [,] c = new double[7, 7];
for (int i = 0; i < 7; i++)
for (int j = 0; j < 7; j++)
for (int k = 0; k < 7; k++)
c[i, j] += a[i, k] * b[k, j];
return c;
}
// Function to perform matrix exponentiation
static double [,] mul_expo(double [,] mul, int p)
{
// 7 * 7 identity matrix
double [,] s = {{ 1, 0, 0, 0, 0, 0, 0 },
{ 0, 1, 0, 0, 0, 0, 0 },
{ 0, 0, 1, 0, 0, 0, 0 },
{ 0, 0, 0, 1, 0, 0, 0 },
{ 0, 0, 0, 0, 1, 0, 0 },
{ 0, 0, 0, 0, 0, 1, 0 },
{ 0, 0, 0, 0, 0, 0, 1 }};
// Loop to find the power
while (p != 1)
{
if (p % 2 == 1)
s = matrix_product(s, mul);
mul = matrix_product(mul, mul);
p /= 2;
}
return matrix_product(mul, s);
}
// Function to return the required count
static double expectedSteps(int x)
{
// Base cases
if (x == 0)
return 0;
if (x <= 6)
return 6;
// Multiplier matrix
double [,]mul = {{(double)7 / 6, 1, 0, 0, 0, 0, 0 },
{ 0, 0, 1, 0, 0, 0, 0 },
{ 0, 0, 0, 1, 0, 0, 0 },
{ 0, 0, 0, 0, 1, 0, 0 },
{ 0, 0, 0, 0, 0, 1, 0 },
{ 0, 0, 0, 0, 0, 0, 1 },
{(double) - 1 / 6, 0, 0,
0, 0, 0, 0 }};
// Finding the required multiplier
// i.e mul^(X-6)
mul = mul_expo(mul, x - 6);
// Final answer
return (mul[0, 0] + mul[1, 0] + mul[2, 0] +
mul[3, 0] + mul[4, 0] + mul[5, 0]) * 6;
}
// Driver code
public static void Main(String[] args)
{
int n = 10;
Console.Write("{0:f5}", expectedSteps(n - 1));
}
}
// This code is contributed by Rajput-Ji
7.36111
上述方法的时间复杂度将为O(343 * log(N))或简单地为O(log(N)) 。