動態規劃——硬幣找零
阿新 • • 發佈:2018-08-02
max 關系 i++ 是否 coin fine 個數 names std
動態規劃問題,主要在於需要想清楚遞推關系,num[i][j]表示能使用 i 種硬幣時,得到 j 零錢的最優解。
想來就是首先假設只能使用第一種硬幣 1 ,那麽會得到num[ 1 : n] = {1,2,3,4.....n},然後在此基礎上,我們引入第二種硬幣 2 ,考慮num[i][j],此時存在兩種情況,即加入硬幣是否使得硬幣個數減少,答案是肯定的。當然要先判斷2能放入多少個,這裏設為k個,然後遞歸求值。
// Study.cpp: 定義控制臺應用程序的入口點。 // #include "stdafx.h" #include <iostream> #include <vector> #include <unordered_map> #include <unordered_set> #include <queue> #include <string> #include <algorithm> #include <sstream> #include <set> #include <stack> #define INT_MAX 2147483647 // maximum (signed) int value #define INT_MIN (-2147483647 - 1) // minimum (signed) int value ; #define Min(x,y) (x)<(y)?(x):(y) using namespace std; int Max(int a, int b) { return a > b ? a : b; } void coin_solution(int m, vector<int> &value) { int n = value.size()-1; vector<vector<int>> num(n + 1, vector<int>(m+1,INT_MAX)); //for (int j = 1; j <= m; j++) // if (num[1][j] % value[1] == 0) // num[1][j] = j / value[1]; for (int i = 0; i <= n; i++) num[i][0] = 0; for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { if(value[i] <= j) for (int k = 1; k <= j / value[i]; k++) num[i][j] = Min(num[i - 1][j], num[i - 1][j - k * value[i]] + k); else num[i][j] = num[i - 1][j]; } } for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) if (num[i][j] == INT_MAX) cout << -1 << " "; else cout << num[i][j] << " "; cout << endl; } if (num[n][m] != INT_MAX) cout << num[n][m] << endl; else cout << -1 << endl; } int main() { int M = 65; vector<int> value = {0,1,2,5,21,25}; coin_solution(M,value); system("pause"); return 0; }
動態規劃——硬幣找零