给定一个长度为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
Javascript
7.36111
上述方法的时间复杂度为 O(343 * log(N)) 或简单为O(log(N)) 。
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。