📌  相关文章
📜  到达棋盘末端的预期移动次数|矩阵求幂

📅  最后修改于: 2021-09-16 11:11:47             🧑  作者: Mango

给定一个长度为N的线性板,编号从1N ,任务是找到到达板的N单元所需的预期移动次数,如果我们从编号为1 的单元开始,并且在每一步我们掷一个立方骰子决定下一步行动。此外,我们不能超出董事会的范围。请注意,预期的移动次数可以是小数。

例子:

方法:基于动态规划的方法已经在之前的文章中讨论过。在本文中,将讨论一种更优化的方法来解决这个问题。这个想法是使用一种称为矩阵求幂的技术。
让我们将 A n定义为到达长度为N + 1的棋盘末端的预期移动次数。

递推关系为:

现在,递推关系需要转换成合适的格式。

矩阵求幂技术可以在这里应用于上述递推关系。
基数将为{6, 6, 6, 6, 6, 6, 0}对应于{A6, A5, A4…, A0}
乘数将是

要查找值:

  • 求 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 现场工作专业课程学生竞争性编程现场课程