public void handleChangeRequest(int requestValue, int numHalfDollar) {
		myNumHalfDollar = Math.min(numHalfDollar, MAX_NUM_HALF_DOLLAR);
		initializeDpState();
		DpState bestState = new DpState();
		int bestNumCoins = 0;
		int totalValue = requestValue;
		int bestNumHalfDollar = 0;
		double bestMassValue = Double.MAX_VALUE;
		outerLoop:
		for (int i = 0; i < MAX_NUM_COINS; i++)
			for (int j = 0; j <= myNumHalfDollar; j++) {
				bestState = memoization(i, requestValue, j);
				if (bestState.isValid() && bestState.mass < bestMassValue) {
					bestNumCoins = i;
					bestNumHalfDollar = j;
					bestMassValue = bestState.mass;
					break outerLoop;
				}
			}
		//System.out.println(bestState.mass + " " + bestState.lastCoinValue);
		HashMap<Integer, Integer> numCoinForEach = new HashMap<Integer, Integer>();
		for (Integer coinValue: myCoinMasses.keySet()) {
			numCoinForEach.put(coinValue, 0);
		}
		DpState stateIterator = bestState;
		// while the DpState is valid and is not edge cases (lastCoinValue = 0 when number of coins is 0)
		while (stateIterator.isValid() && stateIterator.lastCoinValue != 0) {
			int number = numCoinForEach.get(stateIterator.lastCoinValue);
			numCoinForEach.put(stateIterator.lastCoinValue, number + 1); // increment the number by 1
			bestNumCoins--;
			totalValue -= stateIterator.lastCoinValue;
			if (stateIterator.lastCoinValue == 50)
				bestNumHalfDollar--;
			stateIterator = dp[bestNumCoins][totalValue][bestNumHalfDollar];
		}
		printChange(numCoinForEach);
	}