📜  预计将达到董事会结束的举动数量|矩阵求幂

📅  最后修改于: 2021-04-27 19:22:30             🧑  作者: 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


输出:
7.36111

上述方法的时间复杂度将为O(343 * log(N))或简单地为O(log(N))