【动态规划】 动态规划最重要的两个问题就是 状态的定义 和 状态转移方程的定义。 /***************************** 换钱方法 给定数组arr,arr中所有的值都是整数且不重复,每个值代表一种面值的货币, 每种面值的货币可以使用任意张,再给定一个整数,aim代表要找的钱数,求换钱有多少种方法。 ***********************************/ 思路: 1,对 arr 从小到大排序。 2,建一张二维表 dp[m][n+1],其中 m 表示 arr 中货币的种类数, n 表示 aim。 如:arr={2,3,4}, aim=5; | 0 1 2 3 4 5 --|--------------- 2 | 1 0 1 0 1 0 3 | 1 0 0 0 0 0 4 | 1 0 0 0 0 0 | 3,状态: 初始化 dp 表, dp[i][j] 表示目标钱数 j 用 arr[0],...,arr[i] 对应的货币来换的方法数。例如 dp[4][1] 表示用 2和3 换 货币 4 的方法数。 4,状态转移:填充 dp 中的其他元素 dp[i][j]=dp[i-1][j]+dp[i][j-arr[i]] 时间复杂度 O(m*n) /*********************************** 代码: class Solution{ public: int changeMoneyWays(vector<int>& array, int aim){ sort(array.begin(), array.end()); const int n = array.size(); // 构造二维 dp 的行 const int m = aim + 1; // 。。。。。。列 vector<vector<int>> dp(n, vector<int>(m, 0)); // 二维的 dp 数组 for (int i = 0; i < n; ++i) // 初始化 dp 第一列 dp[i][0] = 1; for (int j = 1; j < m; ++j) { // 初始化 dp 第一行 if (!(j%array[0])) dp[0][j] = 1; } for (int i = 1; i < n; ++i){ // 填充 dp 的其他部分 for (int j = 1; j < m; ++j){ dp[i][j] += dp[i - 1][j]; // 状态转移 if ( j >= array[i]) dp[i][j] += dp[i][j - array[i]]; } } return dp[n - 1][m - 1]; } };
【动态规划】 换钱方法
最新推荐文章于 2021-05-03 11:36:46 发布