sum为某个值所需要的最小硬币数

dp,时间O(m*n),m为目标值,n为硬币数,空间O(m)

/*
 * Given a list of 'N' coins, their values being in an array A[], return the minimum number of coins required to sum to 'S' (you can use as many coins you want). If it's    not possible to sum to 'S', return -1
 *
 *
 * Input #01:
 * Coin denominations: { 5,5,5,5,5 }
 * Required sum (S): 11
 *
 * Output #01:
 * -1
 */
#include <iostream>
#include <vector>
using namespace std;
#define MAX 0x7fffffff

int MinCoins(const vector<int>& vals, int target) {
  if (target <= 0 || vals.empty()) return -1;
  vector<int> pre_res;
  vector<int> cur_res;
  pre_res.resize(target + 1, MAX);
  cur_res.resize(target + 1, MAX);
  for (int i = 0; i < vals.size(); ++i) {
    for (int j = 0; j <= target; ++j) {
      if (j + vals[i] <= target) {
        if (pre_res[j] == MAX) continue;
        cur_res[j + vals[i]] = min(pre_res[j + vals[i]], pre_res[j] + 1);
      }
    }
    if (vals[i] <= target) cur_res[vals[i]] = 1;
    pre_res.swap(cur_res);
  }

  return pre_res.back() == MAX ? -1 : pre_res.back();
}

int main() {
  int arr[] = {1,2,3,3,4,5};
  vector<int> vals;
  vals.insert(vals.end(), arr, arr + sizeof(arr)/4);
  cout << MinCoins(vals, 8) << endl;
  return 1;
}

 

posted @ 2013-09-15 23:40  dmthinker  阅读(147)  评论(0)    收藏  举报