leetcode-21-knapsack
322. Coin Change
Write a function to compute the fewest number of coins that you need to make up that amount. If that amount of
money cannot be made up by any combination of the coins, return -1
.You may assume that you have an infinite
number of each kind of coin.
解题思路:
比较典型的背包问题。这里f[i]存储金额为i时使用硬币的最小数目,c[i]是硬币的价值,w[i]都为1,表示使用一个这样的硬币。
状态转移方程:f[i] = min(f[i], f[i-coins[j]+1),针对i >= coins[j]。
注意:数组要初始化。。f[i]都设为amount+1(作为一个最大值)。f[0]=0。
int coinChange(vector<int>& coins, int amount) { if (amount == 0) return 0; int f[amount + 1]; int i, j; // initialization f[0] = 0; for (i = 0; i <= amount; i++) { // initialization if (i > 0) f[i] = amount + 1; for (j = 0; j < coins.size(); j++) { if (i >= coins[j]) { if (f[i - coins[j]] + 1 < f[i]) { f[i] = f[i - coins[j]] + 1; } } } } // if amount can not be reached, f[amount] = amount+1 return f[amount] > amount ? -1:f[amount]; }
416. Partition Equal Subset Sum
Given a non-empty array containing only positive integers, find if the array can be partitioned into two subsets such that the sum of elements in both subsets is equal.
解题思路:
首先,如果所有数目的和是奇数,那么是false。然后我们看一下sum /= 2是否可以得到。状态转移方程:
dp[j] = max(dp[j], dp[j-nums[i] + nums[i])。初始化dp[0] = 0, dp[i] = sum+1。
如果说几个数相加可以得到sum,则另外几个相加也可以得到sum。因此只要看dp[sum]是否为sum即可。
bool canPartition(vector<int>& nums) { int sum = 0; for (int i = 0; i < nums.size(); i++) { sum += nums[i]; } if (sum % 2 != 0) return false; sum /= 2; int dp[sum + 1] = {sum + 1}; dp[0] = 0; for (int i = 0; i < nums.size(); i++) { for (int j = sum; j >= nums[i]; j--) { if (dp[j - nums[i]] + nums[i] > dp[j]) dp[j] = dp[j - nums[i]] + nums[i]; } } return dp[sum] == sum; }