Problem:
Coin Changing Problem

Find the minimum number of coins to make change for n cents using coins of denominations d1, d2,.., dm. The coins can be used any number of times.

Input

n m
d1 d2 ... dm

Two integers n and m are given in the first line. The available denominations are given in the second line.

Output

Print the minimum number of coins in a line.

Constraints

1 ≤ n ≤ 50000

1 ≤ m ≤ 20

1 ≤ denomination ≤ 10000

The denominations are all different and contain 1.

Sample Input 1

55 4
1 5 10 50

Sample Output 1

2

Sample Input 2

15 6
1 2 7 8 12 50

Sample Output 2

2

Sample Input 3

65 6
1 2 7 8 12 50

Sample Output 3

3

Solution in JavaScript (judge verdict: Time Limit Exceeded)

const input = require('fs').readFileSync('/dev/stdin', 'utf8');

const list = input.trim().split('\n');
const [ n, m ]= list[0].split(' ');
const cm = list[1].trim().split(' ');

const genKey = (...args) => {
  const key = args.join(':');
  return key;
};

const tailRecursion = (i, m) => {

};

const dp = new Map();
const memo = (count, targetList) => {
  const nextTargetSet = new Set();
  for (let i = 0; i < targetList.length; i++) {
    const target = targetList[i];
    const key = genKey(count, target);
    let result = 0;
    if (dp.has(key)) {
      return dp.get(key);
    } if (target === 0) {
      return count;
    }
    for (let i = 0; i < Number(m); i++) {
      const nextTarget = target - Number(cm[i]);
      if (nextTarget >= 0) {
        nextTargetSet.add(nextTarget);
      }
    }
  }

  const nextTargetList = [...nextTargetSet.values()];
  return memo(count + 1, nextTargetList);
}

console.log(memo(0, [Number(n)]));