web-dev-qa-db-fra.com

n étapes avec 1, 2 ou 3 étapes effectuées. Combien de façons d'arriver au sommet?

Si nous avons n étapes et que nous pouvons monter 1 ou 2 étapes à la fois, il existe une relation de Fibonacci entre le nombre d’étapes et les moyens de les gravir. IF et SEULEMENT si nous ne comptons pas 2 + 1 et 1 + 2 comme différents.

Cependant, ce n'est plus le cas, en plus de devoir ajouter une troisième option en 3 étapes. Comment puis-je faire cela?

Ce que j'ai:

1 step = 1 way
2 steps = 2 ways: 1+1, 2
3 steps = 4 ways: 1+1+1, 2+1, 1+2, 3

Je ne sais pas où aller à partir d'ici pour connaître le nombre de voies pour n escaliers

Je reçois 7 pour n = 4 et 14 pour n = 5 j’obtiens 14 + 7 + 4 + 2 + 1 en faisant la somme de toutes les combinaisons qui le précèdent. donc manières pour n étapes = n-1 voies + n-2 voies + .... 1 voies en supposant que j'ai gardé toutes les valeurs. Programmation DYNAMIQUE . 1 2 et 3 étapes constitueraient le scénario de base, est-ce exact?

15
MD-4

Je dirais que la formule se présentera de la manière suivante:

K(1) = 1
K(2) = 2
k(3) = 4
K(n) = K(n-3) + K(n-2) + K(n - 1)

La formule dit que pour atteindre la nième étape, nous devons d’abord atteindre: 

  • n-3e étape et ensuite 3 étapes à la fois, c'est-à-dire K (n-3)
  • ou n-2 'étape et ensuite prendre 2 étapes à la fois, à savoir K (n-2)
  • ou n-1e étape, puis effectuez une étape à la fois, à savoir K (n-1)

K (4) = 7, K(5) = 13 etc.

Vous pouvez utiliser la formule récursive ou utiliser la programmation dynamique.

33
Michał Komorowski

Ceci est ma solution dans Ruby:

# recursion requirement: it returns the number of way up
# a staircase of n steps, given that the number of steps
# can be 1, 2, 3

def how_many_ways(n)
  # this is a bit Zen like, if 0 steps, then there is 1 way
  # and we don't even need to specify f(1), because f(1) = summing them up
  # and so f(1) = f(0) = 1
  # Similarly, f(2) is summing them up = f(1) + f(0) = 1 + 1 = 2
  # and so we have all base cases covered
  return 1 if n == 0

  how_many_ways_total = 0
  (1..3).each do |n_steps|
    if n >= n_steps
      how_many_ways_total += how_many_ways(n - n_steps)
    end
  end
  return how_many_ways_total
end

0.upto(20) {|n| puts "how_many_ways(#{n}) => #{how_many_ways(n)}"}


et une version plus courte:

def how_many_ways(n)
  # this is a bit Zen like, if 0 steps, then there is 1 way
  # if n is negative, there is no way and therefore returns 0
  return 1 if n == 0
  return 0 if n < 0
  return how_many_ways(n - 1) + how_many_ways(n - 2) + how_many_ways(n - 3)
end

0.upto(20) {|n| puts "how_many_ways(#{n}) => #{how_many_ways(n)}"}


et une fois que vous savez qu'il ressemble à la série fibonacci, vous n'utiliseriez pas de récursivité, mais utilisez une méthode itérative:

# 
# from 0 to 27: recursive: 4.72 second
#               iterative: 0.03 second
#

def how_many_ways(n)
  arr = [0, 0, 1]
  n.times do
    new_sum = arr.inject(:+)    # sum them up
    arr.Push(new_sum).shift()
  end
  return arr[-1]
end

0.upto(27) {|n| puts "how_many_ways(#{n}) => #{how_many_ways(n)}"}


sortie:

how_many_ways(0) => 1
how_many_ways(1) => 1
how_many_ways(2) => 2
how_many_ways(3) => 4
how_many_ways(4) => 7
how_many_ways(5) => 13
how_many_ways(6) => 24
how_many_ways(7) => 44
how_many_ways(8) => 81
how_many_ways(9) => 149
how_many_ways(10) => 274
how_many_ways(11) => 504
how_many_ways(12) => 927
how_many_ways(13) => 1705
  .
  .
how_many_ways(22) => 410744
how_many_ways(23) => 755476
how_many_ways(24) => 1389537
how_many_ways(25) => 2555757
how_many_ways(26) => 4700770
how_many_ways(27) => 8646064

J'aime l'explication de @ MichałKomorowski et le commentaire de @rici. Je pense que si cela dépend de la connaissance de K(3) = 4, il faut alors compter manuellement.

3

Obtenez facilement l'intuition du problème:

Pensez que vous montez des escaliers et que les mesures que vous pouvez prendre sont 1 & 2

Le total non. des moyens d'atteindre l'étape 4 = total non. des moyens d'atteindre l'étape 3 + Nombre total de moyens d'atteindre l'étape 2

Comment?

Fondamentalement, il n’ya que deux étapes possibles à partir desquelles vous pouvez atteindre l’étape 4. 

  1. Soit vous êtes à l'étape 3 et faites un pas
  2. Ou vous êtes à l'étape 2 et faites deux pas 

Ce sont les seules possibilités par lesquelles vous pouvez atteindre l'étape 4

De même, il n'y a que deux façons possibles d'atteindre l'étape 2 

  1. Soit vous êtes à l'étape 1 et faites un pas
  2. Ou vous êtes à l'étape 0 et faites deux pas

F(n) = F(n-1) + F(n-2)

F (0) = 0 et F(1) = 1 sont les cas de base. À partir de là, vous pouvez commencer à construire F (2), F(3), etc. Ceci est similaire à la série Fibonacci.

Si le nombre d’étapes possibles est augmenté, disons [1,2,3]. Désormais, vous disposez d’une option supplémentaire pour chaque étape, c’est-à-dire que vous pouvez sauter directement de trois étapes précédentes.

La formule deviendrait alors

F(n) = F(n-1) + F(n-2) + F(n-3)

Regardez cette vidéo pour comprendre Problème d'escalier Série Fibonacci

Compréhension facile du code: problème d'escalier geeksforgeeks

2
Siva Prakash
def count(steps):
  sol = []
  sol.append(1)
  sol.append(1 + sol[0])
  sol.append(1 + sol[1] + sol[0])


  if(steps > 3):
    for x in range(4, steps+1):
        sol[(x-1)%3] = sum(sol)


return sol[(steps-1)%3]
1
Suyash Shetty

Compter les moyens d'atteindre le nth escalier utilisant les étapes 1, 2, 3.

Nous pouvons compter en utilisant des méthodes récursives simples.

// Header File
#include<stdio.h>
// Function prototype for recursive Approch
int findStep(int);
int main(){
    int n;
    int ways=0;
    ways = findStep(4);
    printf("%d\n", ways);
return 0;
}
// Function Definition
int findStep(int n){
    int t1, t2, t3;
    if(n==1 || n==0){
        return 1;
    }else if(n==2){
        return 2;
    }
    else{
        t3 = findStep(n-3);
        t2 = findStep(n-2);
        t1 = findStep(n-1);
        return t1+t2+t3;
    }
}
1
Prakhar Agrawal

Ma solution est en Java ... J'ai décidé de résoudre ce problème de bas en haut.

Je commence par avoir un tableau vide de chemins actuels [] À chaque étape, j'ajouterai toutes les tailles de pas possibles {1,2,3}

Première étape [] -> [[1], [2], [3]]
Deuxième étape [[1], [2], [3]] -> [[1,1], [1,2], [1,3], [2,1], [2,2 ], [2,3], [3,1] [3,2], [3,3]]



Itération 0: []
Itération 1: [[1], [2], [3]]
Itération 2: [[1,1], [1,2], [1,3], [2,1], [2,2], [2,3], [3,1], [3,2 ], [3,3]]
Itération 3 [[1,1,1], [1,1,2], [1,1,3] ....]

Les longueurs de séquence sont les suivantes: .1. 1 2 3 5 8 13 21

Ma fonction step s'appelle build

public class App {



public static boolean isClimedTooHigh(List<Integer> path, int maxSteps){
    int sum = 0;
    for (Integer i : path){
        sum+=i;
    }
    return sum>=maxSteps;
}

public static void modify(Integer x){
    x++;
    return;
}

///  1    2   3

/// 11 12 13
/// 21 22 23
/// 31 32 33

///111 121
public static boolean build(List<List<Integer>> paths, List<Integer> steps, int maxSteps){
    List<List<Integer>> next = new ArrayList<List<Integer>>();
    for (List<Integer> path : paths){
        if (isClimedTooHigh(path, maxSteps)){
            next.add(path);
        }
        for (Integer step : steps){
            List<Integer> p = new ArrayList<Integer>(path);
            p.add(step);
            next.add(p);
        }
    }
    paths.clear();
    boolean completed = true;
    for (List<Integer> n : next){
        if (completed && !isClimedTooHigh(n, maxSteps))
            completed = false;
        paths.add(n);
    }

    return completed;
}

public static boolean isPathEqualToMax(List<Integer> path, int maxSteps){
    int sum = 0;
    for (Integer i : path){
        sum+=i;
    }
    return sum==maxSteps;
}

public static void calculate( int stepSize, int maxSteps ){
    List<List<Integer>> paths = new ArrayList<List<Integer>>();
    List<Integer> steps = new ArrayList<Integer>();
    for (int i =1; i < stepSize; i++){
        List<Integer> s = new ArrayList<Integer>(1);
        s.add(i);
        steps.add(i);
        paths.add(s);
    }
    while (!build(paths,steps,maxSteps));
    List<List<Integer>> finalPaths = new ArrayList<List<Integer>>();
    for (List<Integer> p : paths){
        if (isPathEqualToMax(p, maxSteps)){
            finalPaths.add(p);
        }
    }

    System.out.println(finalPaths.size());
}
public static void main(String[] args){
    calculate(3,1);
    calculate(3,2);
    calculate(3,3);
    calculate(3,4);
    calculate(3,5);
    calculate(3,6);
    calculate(3,7);

    return;
}

}

0
Robert I

Vous trouverez ci-dessous plusieurs façons d’utiliser les étapes 1, 2 et 3.

1: 1
2: 11   2
3: 111 12 21 3
4: 1111 121 211 112 22 13 31
5: 11111 1112 1121 1211 2111 122 212 221 113 131 311 23 32
6: 111111 11112 11121 11211 12111 21111 1113 1131 1311 3111 123 132 312 321 213 231 33 222 1122 1221 2211 1212 2121 2112

Donc, selon la combinaison ci-dessus, le soln devrait être:

K(n) = K(n-3) + K(n-2) + K(n - 1)
k(6) = 24 which is k(5)+k(4)+k(3) = 13+7+4
0
Lokesh Nayak

Solution C++ basée sur la mémorisation récursive: Vous demandez à un escalier combien de manières nous pouvons atteindre? Si ce n'est pas l'escalier le plus haut, sa va demander à tous ses voisins et le résumer et vous rendre le résultat. Si c'est l'escalier le plus haut sa va dire 1.

vector<int> getAllStairsFromHere(vector<int>& numSteps,  int& numStairs, int currentStair)
{
    vector<int> res;

    for(auto it : numSteps)
        if(it + currentStair <= numStairs)
            res.Push_back(it + currentStair);

    return res;
}


int numWaysToClimbUtil(vector<int>& numSteps, int& numStairs, int currentStair, map<int,int>& memT)
{
    auto it = memT.find(currentStair);
    if(it != memT.end())
        return it->second;

    if(currentStair >= numStairs)
        return 1;

    int numWaysToClimb = 0;
    auto choices = getAllStairsFromHere(numSteps,  numStairs, currentStair);
    for(auto it : choices)
        numWaysToClimb += numWaysToClimbUtil(numSteps, numStairs, it, memT);


    memT.insert(make_pair(currentStair, numWaysToClimb));
    return memT[currentStair];
}


int numWaysToClimb(vector<int>numSteps, int numStairs)
{
    map<int,int> memT;
    int currentStair = 0;
    return numWaysToClimbUtil(numSteps, numStairs, currentStair, memT);
}
0
Raghav Navada

Comptez le nombre total de façons de parcourir la distance avec 1, 2 et 3 étapes.

La complexité temporelle de la solution de récursivité est exponentielle, c'est-à-dire O (3n).

Puisque les mêmes problèmes de sous sont résolus à nouveau, ce problème a une propriété de sous-problèmes qui se chevauchent. Donc, le problème de somme carrée a les propriétés d’un problème de programmation dynamique.

public class MaxStepsCount {

     /** Dynamic Programming. */
     private static int getMaxWaysDP(int distance) {

           int[] count = new int[distance+1];
           count[0] = 1;
           count[1] = 1;
           count[2] = 2;

           /** Memorize the Sub-problem in bottom up manner*/
           for (int i=3; i<=distance; i++) {
                count[i] = count[i-1] + count[i-2] + count[i-3];               
           }
           return count[distance];
     }


     /** Recursion Approach. */
     private static int getMaxWaysRecur(int distance) {
           if(distance<0) {
                return 0;
           } else if(distance==0) {
                return 1;
           }
           return getMaxWaysRecur(distance-1)+getMaxWaysRecur(distance-2)
                     +getMaxWaysRecur(distance-3);
     }

     public static void main(String[] args) {
           // Steps pf 1, 2 and 3.
           int distance = 10;

           /** Recursion Approach. */
           int ways = getMaxWaysRecur(distance);
           System.out.println(ways);

           /** Dynamic Programming. */
           ways = getMaxWaysDP(distance);
           System.out.println(ways);
     }
}

Mon article sur ce blog:

http://javaexplorer03.blogspot.in/2016/10/count-number-of-ways-to-cover-distance.html

0
Rajesh Dixit

Implémentation récursive Java basée sur Réponse de Michał :

public class Tribonacci {
    // k(0) = 1
    // k(1) = 1
    // k(2) = 2
    // k(3) = 4
    // ...
    // k(n) = k(n-3) + k(n-2) + k(n - 1)

    static int get(int n) {
        if (n == 0) {
            return 1;
        } if (n == 1) {
            return 1;
        } else if (n == 2) {
            return 2;
        //} else if (n == 3) {
        //    return 4;
        } else {
            return get(n - 3) + get(n - 2) + get(n - 1);
        }
    }

    public static void main(String[] args) {
        System.out.println("Tribonacci sequence");
        System.out.println(Tribonacci.get(1));
        System.out.println(Tribonacci.get(2));
        System.out.println(Tribonacci.get(3));
        System.out.println(Tribonacci.get(4));
        System.out.println(Tribonacci.get(5));
        System.out.println(Tribonacci.get(6));
    }
}
0
nacho4d

Voici un O(Nk) Implémentation Java utilisant la programmation dynamique:

public class Sample {
    public static void main(String[] args) {
        System.out.println(combos(new int[]{4,3,2,1}, 100));
    }

    public static int combos(int[] steps, int stairs) {
        int[][] table = new int[stairs+1][steps.length];
        for (int i = 0; i < steps.length; i++) {

            for (int n = 1; n <= stairs; n++ ) {
                int count = 0;
                if (n % steps[i] == 0){
                    if (i == 0)
                        count++;
                    else {
                        if (n <= steps[i])
                            count++;
                    }
                }

                if (i > 0 && n > steps[i]) {
                    count += table[n - steps[i]][i];
                }

                if (i > 0)
                    count += table[n][i-1];

                table[n][i] = count;
            }
        }

        for (int n = 1; n < stairs; n++) {
            System.out.print(n + "\t");
            for (int i = 0; i < steps.length; i++) {
                System.out.print(table[n][i] + "\t");
            }
            System.out.println();
        }
        return table[stairs][steps.length-1];
    }
}

L'idée est de remplir le tableau suivant 1 colonne à la fois de gauche à droite:

N    (4)    (4,3)  (4,3,2) (4,3,2,1)
1   0   0   0   1   
2   0   0   1   2   
3   0   1   1   3   
4   1   1   2   5   
5   0   0   1   6   
6   0   1   3   9   
7   0   1   2   11  
8   1   1   4   15  
9   0   1   3   18  
10  0   1   5   23  
11  0   1   4   27  
12  1   2   7   34  
13  0   1   5   39  
..
..
99  0   9   217 7803
100             8037
0
Pavan Achanta