<p>You are given a <strong>0-indexed</strong> array of integers <code>nums</code>, and an integer <code>target</code>.</p>

<p>Return <em>the <strong>length of the longest subsequence</strong> of</em> <code>nums</code> <em>that sums up to</em> <code>target</code>. <em>If no such subsequence exists, return</em> <code>-1</code>.</p>

<p>A <strong>subsequence</strong> is an array that can be derived from another array by deleting some or no elements without changing the order of the remaining elements.</p>

<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>

<pre>
<strong>Input:</strong> nums = [1,2,3,4,5], target = 9
<strong>Output:</strong> 3
<strong>Explanation:</strong> There are 3 subsequences with a sum equal to 9: [4,5], [1,3,5], and [2,3,4]. The longest subsequences are [1,3,5], and [2,3,4]. Hence, the answer is 3.
</pre>

<p><strong class="example">Example 2:</strong></p>

<pre>
<strong>Input:</strong> nums = [4,1,3,2,1,5], target = 7
<strong>Output:</strong> 4
<strong>Explanation:</strong> There are 5 subsequences with a sum equal to 7: [4,3], [4,1,2], [4,2,1], [1,1,5], and [1,3,2,1]. The longest subsequence is [1,3,2,1]. Hence, the answer is 4.
</pre>

<p><strong class="example">Example 3:</strong></p>

<pre>
<strong>Input:</strong> nums = [1,1,5,4,5], target = 3
<strong>Output:</strong> -1
<strong>Explanation:</strong> It can be shown that nums has no subsequence that sums up to 3.
</pre>

<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>

<ul>
	<li><code>1 &lt;= nums.length &lt;= 1000</code></li>
	<li><code>1 &lt;= nums[i] &lt;= 1000</code></li>
	<li><code>1 &lt;= target &lt;= 1000</code></li>
</ul>

class Solution:
    def lengthOfLongestSubsequence(self, nums: List[int], target: int) -> int:
        """
        DP problem
        How to design this DP structure?
        It should be the position and target sum structure. 
        At position i, we can form value j with longest length k
        memo[i, j] = k
        initialization memo[0, nums[0]] = 1
        And memo[0, 1 ... target] = 0
        for the next memo[1, min(nums[0], nums[1]), ..., k]
        we know the value depends on the previous
        """
        # n = len(nums)
        # memo = [[-1] * (target+1) for _ in range(n+1)]
        # for i in range(n+1):
        #     memo[i][0] = 0
        # for i in range(1, n+1):
        #     for j in range(1, target+1):
        #         memo[i][j] = memo[i-1][j]
        #         if j >= nums[i-1] and memo[i-1][j - nums[i-1]] != -1:
        #             memo[i][j] = max(memo[i][j], 1 + memo[i-1][j-nums[i-1]])
        # return memo[-1][-1]
        
        # Could update to one array dp
        dp = [0] + [-1] * target                 #  -->   [0,-1,-1,-1, 1,-1,-1,-1]
        for num in nums:                                    #   4    [0,-1,-1,-1, 1,-1,-1,-1]
            for i in reversed(range(num, target+1)):        #   1    [0, 1,-1,-1, 1, 2,-1,-1]
                nxt = dp[i - num] + 1                       #   3    [0, 1,-1, 1, 2, 2,-1, 2]
                dp[i] = max(nxt, dp[i]) if nxt else dp[i]   #   2    [0, 1,-1, 1, 2, 2,-1, 2]
                                                            #   1    [0, 1, 2, 2, 3, 3, 3, 4]
        return dp[-1]   
2441