494.目标和
int findTargetSumWays(vector<int>& nums, int target) {
int sum=0;
//vector<int> dp(1501, 0);
for(int i=0;i<nums.size();i++){
sum+=nums[i];
}
if (abs(target) > sum) return 0; // 此时没有方案
if ((target + sum) % 2 == 1) return 0; // 此时没有方案
int bagSize = (target + sum) / 2;
vector<int> dp(bagSize+1, 0);
dp[0]=1;
for (int i = 0; i <nums.size(); i++) { // 遍历物品
for (int j = bagSize; j >= nums[i]; j--) { // 遍历背包容量// 每一个元素一定是不可重复放入,所以从大到小遍历
dp[j] += dp[j - nums[i]];
}
}
return dp[bagSize];
}
474.一和零
int findMaxForm(vector<string>& strs, int m, int n) {
vector<vector<int>> dp(m+1, vector<int>(n+1,0)); 默认初始化0
for(string str:strs){// 遍历物品
int x=0,y=0;
for(char c:str){
if(c=='0') x++;
else y++;
}
for(int i=m;i>=x;i--){// 遍历背包容量且从后向前遍历!
for(int j=n;j>=y;j--){
dp[i][j]=max(dp[i][j],dp[i-x][j-y]+1);
}
}
}
return dp[m][n];
}
518.零钱兑换II
int change(int amount, vector<int>& coins) {
vector<int> dp(amount+1, 0);
dp[0]=1;
for (int i = 0; i <coins.size(); i++) { // 遍历物品
for (int j = coins[i]; j <= amount; j++) { // 遍历背包容量
dp[j] += dp[j - coins[i]];
}
}
return dp[amount];
}
打印的代码
#include<iostream>
#include<vector>
using namespace std;
int change(int amount, vector<int>& coins) {
vector<int> dp(amount + 1, 0);
dp[0] = 1;
for (int i = 0; i < coins.size(); i++) { // 遍历物品
cout <<endl<< "i = " << i << ": "<<endl;
for (int j = coins[i]; j <= amount; j++) { // 遍历背包容量
dp[j] += dp[j - coins[i]];
cout << "j = " << j << ", dp[j] = " << dp[j] << endl;
}
}
cout << "dp[]:" << endl;
for (int i : dp) {
cout << i << " ";
}
return dp[amount];
}
int main() {
vector<int> coins = { 1,2,5 };
cout << endl<< change(5, coins) << endl;
return 0;
}
假如for改变位置:(变成了排列),是不符合本题的意思的
#include<iostream>
#include<vector>
using namespace std;
int change(int amount, vector<int>& coins) {
vector<int> dp(amount + 1, 0);
dp[0] = 1;
for (int j = 0; j <= amount; j++) { // 遍历背包容量
cout << endl << "j = " << j << ": " << endl;
for (int i = 0; i < coins.size(); i++) { // 遍历物品
if (j - coins[i] >= 0) {
dp[j] += dp[j - coins[i]];
cout << "**有更新**" << j - coins[i] <<" ";
}
cout << "i = " << i << ", dp[j] = " << dp[j] << endl;
}
}
for (int i : dp) {
cout << i << " ";
}
return dp[amount];
}
int main() {
vector<int> coins = { 1,2,5 };
cout << endl << change(5, coins) << endl;
return 0;
}
377. 组合总和 Ⅳ
若是爬楼梯 那道题,拓展成为 一步可以爬m个台阶,就是和本题一样的题目了。求的是排列数还是组合数?(排列数)。
遍历顺序可以颠倒吗?(不可以)
颠倒时 是什么场景(组合?上一题518.零钱兑换II),不颠倒又是什么场景?(本题377. 组合总和 Ⅳ 以及爬楼梯 一步可以爬m个台阶)
如果求组合数就是外层for循环遍历物品,内层for遍历背包。
如果求排列数就是外层for遍历背包,内层for循环遍历物品。
int combinationSum4(vector<int>& nums, int target) {
vector<int> dp(target + 1, 0);
dp[0] = 1;
for (int j = 0; j<= target; j++) { // 遍历背包
for (int i = 0; i< nums.size(); i++) { // 遍历物品
if (j - nums[i] >= 0 && dp[j] < INT_MAX - dp[j - nums[i]]) {
//if (j - nums[i] >= 0 ) {
dp[j] += dp[j - nums[i]];
}
}
}
return dp[target];
}
爬楼梯 那道题,拓展成为 一步可以爬m个台阶
int climbStairs(int n) {
vector<int> dp(n + 1, 0);
dp[0] = 1;
for (int j = 1; j <= n; j++) { // 遍历背包 //共n层楼梯
for (int i = 1; i <= m; i++) { // 遍历物品
if (j - i >= 0) dp[j] += dp[j - i];
}
}
return dp[n];
}
322. 零钱兑换
int coinChange(vector<int>& coins, int amount) {
vector<int> dp(amount + 1, INT_MAX);
dp[0] = 0;
for(int i=0;i<coins.size();i++){// 遍历物品
for(int j=coins[i];j<=amount;j++){// 遍历背包
if(dp[j-coins[i]] != INT_MAX){// 如果dp[j - coins[i]]是初始值则跳过
dp[j]=min(dp[j-coins[i]]+1, dp[j]);
}
}
}
if(dp[amount] == INT_MAX) return -1;
return dp[amount];
}
int coinChange(vector<int>& coins, int amount) {
vector<int> dp(amount + 1, INT_MAX);
dp[0] = 0;
for(int j=1;j<=amount;j++){// 遍历背包
for(int i=0;i<coins.size();i++){// 遍历物品
if(j-coins[i]>=0 && dp[j-coins[i]] != INT_MAX){// 如果dp[j - coins[i]]是初始值则跳过//两个条件不能位置调换,否则会溢出
dp[j]=min(dp[j-coins[i]]+1, dp[j]);
}
}
}
if(dp[amount] == INT_MAX) return -1;
return dp[amount];
}
279.完全平方数
int numSquares(int n) {
vector<int> dp(n + 1, INT_MAX);
dp[0] = 0;
for(int i=1;i*i<=n;i++){// 遍历物品
for(int j=i*i;j<=n;j++){// 遍历背包
dp[j]=min(dp[j-i*i]+1, dp[j]);
}
}
return dp[n];
}
int numSquares(int n) {
vector<int> dp(n + 1, INT_MAX);
dp[0] = 0;
for(int j=0;j<=n;j++){// 遍历背包
for(int i=1;i*i<=j;i++){// 遍历物品
dp[j]=min(dp[j-i*i]+1, dp[j]);
}
}
return dp[n];
}