Your question is equivalent to the decision version of the unbounded knapsack optimization problem. The decision is whether the maximum value (after optimization) is equal to the upper bound. Moreover, the weights and values are identical in your question (i.e. the length is both the weight and the value).
Problem Formulation
The unbounded knapsack optimization problem is as follows:
Given a set of $n$ objects where object $i$ has weight $w_i$ and value $v_i$,
$\>\>$ maximize $\sum_{i=1}^{n} v_i m_i$
$\>\>$ subject to $\sum_{i=1}^{n} w_i m_i \leq W, \\ m_i \in \mathbb{N}$
where $m_i$ denotes the multiplicity of object $i$, and $W$ is some upper bound.
(note that we're using the definition of $\mathbb{N}$ that includes zero here)
The decision version of this problem can be formulated in terms of the optimization version:
Is the maximum value of the unbounded knapsack optimization problem over the given set of objects $(w_i,v_i)^*$ and upper bound $W$ equal to $V$?
Now let's map these descriptions to your particular question. First, note that length of a cuisenaire rod is equal to both its weight and its value. So we can replace every $w_i$ and $v_i$ with just $x_i$. Similarly, the upper bound on the weight is also the target value for the decision problem. So we can replace both $W$ and $V$ with $B$. Finally, since the selection variable $m_i$ is already using the definition of the natural numbers that includes zero, let's be precise and replace every instance of "natural number" in your problem description with "positive integer".
This results in the following problem formulation:
Given some $B$ and a set of $n$ cuisenaire rods of lengths $x_1, x_2, ..., x_n$ where $B \in \mathbb{Z^+} \land \forall x_i (x_i \in \mathbb{Z^+})$,
is the result of maximizing
$\>\>\>\>\>\> \sum_{i=1}^{n} x_i m_i$
subject to
$\>\>\>\>\>\> \sum_{i=1}^{n} x_i m_i \leq B, \\ \>\>\>\>\>\> m_i \in \mathbb{N}$
equal to $B$?
Solution as Recurrence Relation
Since $\forall x_i(x_i \in \mathbb{Z})$, we can most easily solve this knapsack problem by formulating a recurrence relation for it. So let $M[b]$ denote the maximum length less than or equal to $b$ of an unbounded combination of the given cuisenaire rods. The base case is $M[0] = 0$, since we can always select a combination of zero cuisenaire rods (i.e. set every $m_i$ to $0$) whose sum is the maximum value less than or equal to zero (i.e. zero itself).
The recursive case is formulated in terms of reducing the allowable maximum length by the different cuisenaire rod lengths. The idea is to see whether specifying that we have used one of rod $x_1$, $x_2$, ..., or $x_n$ gets us closer to $B$. In specifying that we have used one of rod $x_i$, we may remove that rod from the tally and recurse on the smaller value, i.e. $M[b-x_i]$. In order to find the maximum value, we add the value of the rod that we just removed to whatever the maximum length of the smaller limit is, i.e. $M[b] = x_i + M[b-x_i]$. More specifically, $M[b]$ is equal to the maximum possible value that we could achieve between selecting one rod from all the different rods, i.e. $M[b] = max_{i=1}^{n} (x_i + M[b-x_i])$.
Note that since this is the unbounded knapsack problem, we cannot say whether we will use the selected rod (or any other rod) again in the solution. In terms of formulating the recurrence relation, all we can say for certain is that the selected rod is used at this specific step. The decision about what rod to select next (or even to select this rod again) is left entirely up to the next step in the recursion.
Putting this all together, and assuming that both $B > 0$ and $\forall x_i (x_i > 0)$ in order to avoid wonky edge cases, we get the following recurrence relation:
$ \>\> M[0] = 0, \\ \>\> M[b] = max_{i=1}^{n}(x_i + M[b-x_i]) $
Note that $M[b]$ is undefined for any $b < 0$. If we want to be really precise about it, we could express this formally as $ M[b] = max_{\{x_i | b-x_i \geq 0\}}(x_i + M[b-x_i]) $.
We can now find the maximum length less than or equal to $B$ of any unbounded combination of cuisenaire rods by evaluating $M[B]$. This solves the optimization problem. To solve the decision problem, simply check if $M[B] = B$.
Dynamic Programming
Since $\forall x_i(x_i \in \mathbb{Z})$, we can easily apply dynamic programming by instantiating an array (with all elements initialized to zero) of length $B$. Store and lookup the value of each term in this recurrence relation in that array.
We can optimize this dynamic programming solution in two main ways. First, we can reduce the runtime by iteratively filling in the array from $M[0]$ to $M[B]$ in order to avoid the function call overhead of recursively starting at $M[B]$.
Second, we can reduce the space by observing that a circular array of size $\mathcal{max_{i=1}^{n}(x_i)}+1$ is sufficient to hold as many previously calculated values as is required to calculate any $M[b]$. This is because for any $b$, in order to calculate $M[b]$ we will only need to look as far "back" in the array as $max_{i=1}^{n}(x_i)$. For example, if $x_1 = 5$ and $x_2 = 7$, then to calculate $M[20]$ we would only need to look at $M[20-5]$ and $M[20-7]$.
Furthermore, if desired, we can also preprocess the set of rods to determine if there is a simpler solution (i.e. check if $\exists x_i (B \> mod \> x_i \equiv 0)$, to remove rods that cannot be part of the solution (i.e. $x_i > B$), to remove redundant rods (i.e. $x_i$ is redundant if $\exists j \neq i (x_j \> mod \> x_i \equiv 0)$), etc.
Example
Here is a working example in Python (without any of the preprocessing optimizations):
def cuisenaire(B, rods):
"""
B is a positive integer that serves as the targeted upper bound (inclusive).
Rods is a list of cuisenaire rods with positive integer lengths listed
in ascending order.
"""
dp = [0] * (max(rods)+1) # dynamic programming workspace
for i in range(1,B+1): # iteratively fill DP workspace (1 to B, inclusive)
for rod in rods: # evaluate each first-order subproblem
if i - rod >= 0: # dp[index] undefined for index < 0
temp = rod + dp[(i - rod) % len(dp)] # the core recurrence relation
if temp > dp[i % len(dp)]: # if this value is greater than other,
dp[i % len(dp)] = temp # then update DP cell to greater value
else:
break # optimization, not required for correctness
return dp[B % len(dp)] == B # solve the decision problem
The time complexity of this code is $O (B \cdot n)$ which is B * len(rods)
.
The space complexity of this code is $O (max_{i=1}^{n}(x_i))$ which is max(rods)
.