ここでは、部分和問題の中で使える数に使用制限があるケースの問題について、 「プログラミングコンテストチャレンジブック(第2版)」(通称:蟻本)の p63 を例に、python3 で実装する方法を紹介します。
 蟻本では、DP(動的計画法)で実装しており、 配列dp を再利用することで一次元配列にしていますが、ここでは分かりやすさを優先して、二次元配列で実装しています。

# 入力
n = 3
a = [3, 5, 8]
m = [3, 2, 2]
k = 17
#メモ化テーブル(-1 で初期化)
dp =  [ [ -1 for j in range(k + 1)] for _ in range(n+1) ]
#先頭にダミーとして0を代入
dp[0][0] = 0
# 0からkまでの数字について、与えられたaを何個残して作れるか?を配列dpに記述していく
def solve():
    for i in range(n):
        for j in range(k+1):
            # すでに j を作れることが分かっている場合 
            if dp[i][j] >= 0:
                # 全部残せる
                dp[i+1][j] = m[i]
            # j を作ることができない場合
            elif j < a[i] or dp[i+1][j - a[i]] <= 0:
                # できないという意の -1 を記述
                dp[i+1][j] = -1
            # a[i] を1個使えば jを作ることができる場合
            else:
                # dp[i+1][j - a[i]]の場合に残っていたものから1個引いた値を記述
                dp[i+1][j] = dp[i+1][j - a[i]] - 1

if __name__ == '__main__':
    solve()
    if dp[n][k] >= 0:
        print('Yes')
    else:
        print('No')


以上になります。