Space optimised versions of Coin Change and Knapsack Problems in Dynamic Programming
The difference is whether the solution to the "add element i" subproblem being considered (dp[j - weight[i]] or dp[j-a[i]], as the case may be) allows or forbids a contribution from the current element (value of i).

When the inner loop moves right-to-left, at the time dp[j - weight[i]] is evaluated, that table entry has not yet been updated in this iteration of the outer loop, so it definitely does not include a contribution from element i. Thus the candidate solution having value val[i] + dp[j - weight[i]] includes exactly one copy of element i (and the other candidate solution, dp[j], includes exactly zero copies of it).

OTOH, when the inner loop moves left-to-right, at the time dp[j - weight[i]] is evaluated, that table entry has already been updated in this outer loop cycle, so it may represent a solution that already contains an element i, to which we are now considering adding a second element i. In fact it may already contain multiple copies of element i, since that table entry may have been computed as the result of choosing val[i] + dp[j - weight[i] - weight[i]], etc.