各种背包问题

本文详细探讨了各种类型的背包问题,包括01背包、完全背包、多重背包、混合背包问题、二维费用背包、分组背包和有依赖的背包问题,并提供了相关题目和代码实现,旨在帮助读者理解和解决这类问题。
摘要由CSDN通过智能技术生成

背包问题

主要大纲来自于 崔添翼 (Tianyi Cui)《背包九讲》,本博客主要为代码实现及一些小思路。此外,代码中变量名会尽量统一,可能与原题给出变量名误差较大。

一、01 背包问题

代码相关题目:P1048 [NOIP2005 普及组] 采药

空间:O(VN)
时间:O(VN)

#include<bits/stdc++.h>

using namespace std;

const int N=1010;

int n,v;
int c[N],w[N];
int f[N][N];

int main(){
   
	scanf("%d%d",&v,&n);
	for(int i=1;i<=n;i++){
   
		scanf("%d%d",&c[i],&w[i]);
	}
	for(int i=1;i<=n;i++){
   
		for(int j=1;j<=v;j++){
   
			f[i][j]=f[i-1][j];
			if(c[i]<=j) f[i][j]=max(f[i-1][j],f[i-1][j-c[i]]+w[i]);
		}
	}
	printf("%d",f[n][v]);
	return 0;
}

空间:O(V)
时间:O(VN)

#include<bits/stdc++.h>

using namespace std;

const int N=1010;

int n,v,c[N],w[N],f[N];

void zero_one_pack(int f[],int ci,int wi){
   
	for(int j=v;j>=ci;j--) //一定要逆序
		f[j]=max(f[j],f[j-ci]+wi);
}

int main(){
   
	scanf("%d%d",&v,&n);
	for(int i=1;i<=n;i++) scanf("%d%d",&c[i],&w[i]);
	for(int i=1;i<=n;i++) zero_one_pack(f,c[i],w[i]);
	printf("%d",f[v]);
	return 0;
}

可测试数据,发现答案为100

100 3
99 100
50 20
50 30

如果题目中强调要装满背包 (背了不嫌重咩,强迫症福音)

#include<bits/stdc++.h>

using namespace std;

const int N=1010;
const int FINF=-0x3f3f3f3f;

int n,v;
int c[N],w[N];
int f[N];

int main(){
   
	scanf("%d%d",&v,&n);
	for(int i=1;i<=n;i++){
   
		scanf("%d%d",&c[i],&w[i]);
	}
	memset(f,FINF,sizeof(f)); //赋值为负无穷 
	f[0]=0; //唯一满足满背包合法解的“0背包” 
	for(int i=1;i<=n;i++){
   
		for(int j=v;j>=c[i];j--){
   
			f[j]=
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值