当前位置: 首页 > article >正文

代码随想录算法训练营第44天 | 完全背包理论基础 518.零钱兑换II 377.组合总和 Ⅳ

完全背包理论基础

完全背包与01背包只相差在物品是无限取用的。因此和01背包相比第二层对背包容量的遍历应该是正序的,而且正因为这个正序,使得在纯完全背包问题中,背包容量和物品的遍历是可以倒过来的。

#include <bits/stdc++.h>
using namespace std;
int main() {
	int n, bagSize;
	cin >> n >> bagSize;
	vector<int> weight(n, 0);
	vector<int> value(n, 0);
	for(int i = 0; i < n; i++) {
		cin >> weight[i] >> value[i];
	}
	vector<int> dp(bagSize + 1, 0);
	for(int i = 0; i < n; i++) {
		for(int j = weight[i]; j <= bagSize; j++) {
			dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);
		}
	}
	cout << dp[bagSize] << endl;
	return 0;
}

零钱兑换II

Alt
这道题递推式和目标和那道题是一致的,都是解决装满背包的方法数目问题。重点在于遍历顺序,我们前面总结过对于纯完全背包问题,先遍历背包还是先遍历物品都是一样的。
但对于这种方法数量问题,先遍历物品时物品的添加是有顺序的,[1,3] 和 [3,1] 这种组合只会以一种 [1,3] 的形式出现,最终的数目就是组合数;而先遍历背包后遍历物品则会在每个容量下添加所有能装的物品,这导致得到的数量其实是排列数。

class Solution{
public:
	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];
	}
};

组合总和IV

Alt
这道题对应了前面说的排列数目,需要先遍历背包,再遍历物品。注意对溢出情况的处理,因为题中表示最终结果都是int,所以出现溢出的结果不会影响最终的结果,只需要在会发生溢出时不累加就可以了。

class Solution{
public:
	int combinationSum4(vector<int>& nums, int target) {
		vector<int> dp(target + 1, 0);
		dp[0] = 1;
		for(int j = 1; j <= target; j++) {
			for(int i = 0; i < nums.size(); i++) {
				if(j >= nums[i] && dp[j] <= INT_MAX - dp[j - nums[i]]) {
					dp[j] += dp[j - nums[i]];
				}
			}
		}
		return dp[target];
	}
};

http://www.kler.cn/news/234248.html

相关文章:

  • 假期2.7
  • Android 移动应用开发 创建第一个Android项目
  • leetcode:216.组合总和三
  • Mybatis开发辅助神器p6spy
  • 基于JavaWeb的网上订餐项目
  • Unity类银河恶魔城学习记录1-14 AttackDirection源代码 P41
  • 第十四章 以编程方式使用 SQL 网关 - %SQLGatewayConnection 方法和属性
  • 【正在更新】从零开始认识语音识别:DNN-HMM混合系统语音识别(ASR)原理
  • 02 数据库管理 数据表管理
  • 猫头虎分享已解决Bug || KeyError: ‘The truth value of a Series is ambiguous‘
  • nginx stream proxy 模块的ssl连接源码分析
  • python创建pdf文件
  • MySQL篇----第十八篇
  • 20:基于EL与JSTL的产品管理页-Java Web
  • qt-C++笔记之判断一个QLabel上有没有load图片
  • 基于Python的HTTP隧道安全性分析:魔法背后的锁与钥匙
  • 掌握rm命令:Linux文件删除的艺术与安全指南
  • 【书生·浦语大模型实战营】学习笔记1
  • CSS3 基本语法
  • 17:定时器编程实战
  • 微软和苏黎世联邦理工学院开源SliceGPT创新压缩技术节省大量部署资源;OpenAI成立儿童安全团队,防AI误用
  • JavaScript的聚焦:focus/blur
  • Acwing 5469. 有效点对【正难则反+巧妙选择根节点】
  • Netty应用(四) 之 Reactor模型 零拷贝
  • 【算法】排序详解(快速排序,堆排序,归并排序,插入排序,希尔排序,选择排序,冒泡排序)
  • OpenCV-32 膨胀操作
  • 2024PMP考试新考纲-近年PMP真题练一练和很详细解析(3)
  • 【java】简单的Java语言控制台程序
  • golang select两个channel性能稳定,三个channel时性能会发生抖动,为什么?
  • (c语言版)数组去重和排序 题目描述: 给定一个乱序的数组,删除所有的重复元素,使得每个元素只出现一次,并且按照出现的次数从高到低