首页 > 其他分享 >01背包

01背包

时间:2023-02-03 19:22:54浏览次数:36  
标签:typedef 01 int dfs 背包 物品 include

01背包

有 \(N\) 件物品和一个容量是 \(V\) 的背包。每件物品只能使用一次。

第 \(i\) 件物品的体积是 \(v_i\),价值是 \(w_i\)。

求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。
输出最大价值。

输入格式
第一行两个整数,\(N,V\),用空格隔开,分别表示物品数量和背包容积。

接下来有 \(N\) 行,每行两个整数 \(v_i,w_i\),用空格隔开,分别表示第 \(i\) 件物品的体积和价值。

输出格式
输出一个整数,表示最大价值。

数据范围
\(0<N,V≤1000\)
\(0<v_i,w_i≤1000\)
输入样例
4 5
1 2
2 4
3 4
4 5
输出样例:
8

题意

给出n个有体积有价值的物品,任意选取物品组合使得在背包容量有限条件下(m)总价值最大

特点

  1. 每个物品只能选一次
  2. 取最大值

dfs

点击查看代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
using namespace std;

#define X first
#define Y second

typedef pair<int,int> pii;
typedef long long LL;
const char nl = '\n';
const int N = 1010;
int n,m,V,W,cnt;
int v[N],w[N],ans[N];


void dfs(int x){
	if(x > n){
		ans[++cnt] = W;
		return;
	}

	if(V >= v[x]){   //选(注意是>=而不是>)
		V -= v[x];
		W += w[x];
		dfs(x + 1); 
		V += v[x];
	    W -= w[x];
	}
	dfs(x + 1);	//不选

}

void solve(){
	cin >> n >> m;
	V = m;
	for(int i = 1; i <= n; i ++)cin >> v[i] >> w[i];
	dfs(1);
	int res = 0;
	for(int i = 1; i <= cnt; i ++)res = max(res,ans[i]);
	cout << res;
}

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);

	solve();
}

结果: Segmentation Fault
通过了 4/12个数据
原因:在程序运行过程中,如果递归调用的层数过多,会因为系统分配的栈空间溢出引发错误 -> 递归改成递推
许多步骤重复计算了!!! -> 记忆化搜索完善

dp

点击查看代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
using namespace std;

#define X first
#define Y second

typedef pair<int,int> pii;
typedef long long LL;
const char nl = '\n';
const int N = 1010;
int n,m;
int v[N],w[N],f[N][N];
//f[i][j]记录剩余容积为i时选前j个物品的最大值

void solve(){
	cin >> n >> m;
	for(int i = 1; i <= n; i ++)cin >> v[i] >> w[i];
	for(int i = 1; i <= m; i ++){
		for(int j = 1; j <= n; j ++){
			f[i][j] = f[i][j - 1];	//不选
			if(i >= v[j])f[i][j] = max(f[i][j-1],f[i-v[j]][j-1]+w[j]);	//选
		}
	}
	cout << f[m][n];
}

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);

	solve();
}

结果: Accepted
运行时间: 78 ms
运行空间: 4188 KB

优化

点击查看代码
void solve(){
	cin >> n >> m;
	for(int i = 1; i <= n; i ++)cin >> v[i] >> w[i];
	for(int i = 1; i <= n; i ++){
		for(int j = m; j >= v[i]; j --){	//容量在下
			f[j] = max(f[j],f[j-v[i]]+w[i]);
		}
	}
	cout << f[m];
}

结果: Accepted
运行时间: 40 ms
运行空间: 216 KB

标签:typedef,01,int,dfs,背包,物品,include
From: https://www.cnblogs.com/J-12045/p/17090262.html

相关文章

  • CSP201612-3权限查询
            多年后再回头看这道题觉得很简单,写起来还是很复杂,我的书写习惯不好,找bug找了很久。特别注意在构建角色时,一个角色可能会有多个权限,取最大值,又......
  • 智慧自贸,2012亚洲物流信息化国际峰会成功举办
    版权声明:本文章由“上海美华系统有限公司”编辑组汇编而成,未经授权和许可,任何个人或媒体不得对本网站的文章及其他信息资料予以复制、转载、抄袭、改编。上海美华系统有限......
  • Day 01
    Markdown学习二级标题三级标题四级标题字体Hello,Word!左右俩**变粗体Hello,Word!左右*变斜体Hello,Word!左右3个***变斜粗Hello,Word!左右俩~~变删除引用......
  • 亚马逊关于攀岩绳的政策是什么呢?BS EN 892:2012+A2:2021报告如何提交报告呢?
    亚马逊关于攀岩绳的政策是什么呢?攀岩绳又称主绳,是攀登的象征,它为攀登者与保护者之间建立起了一种可靠的远程连接,为操作者提供了一个安全的平衡过渡。亚马逊政策适用的攀岩绳......
  • UCF Local Programming Contest 2012 C. Clean Up the Powers that Be(记住这个错误)
    题意:题意很简单,写起来也不难,唯一需要注意的就是格式了。我是个憨憨,因为我数组开到,然后就到遍历直接写的到,所以就数组越界一直,重写完过了找了好久才发现,以后这种低级错误......
  • CTU Open Contest 2019 B Beer Bill(模拟)
    题意:计算字符串的价格。给多个字符串,每个串占一行。字符串分两种,一种字符串名为只含有个字符,这种字符串的价格定义为。另一种字符串名为,格式是以数字开头......
  • 2019年12月1号总结
    这个周末把银川南京复现赛都打了,自己一个人打的,先说一下对题目的感受,我自己一个人是在没看任何题解的情况下做的,感觉不是特别难,没有难到了那种写不出来的地步,现在想想出题人......
  • 2019年11月27日总结
    写这篇总结的时候应该是28号了,刚刚打完CF洗完了来写这篇总结。这几天的话我主要是看了权值线段树和主席树,因为上周打比赛遇到了一道这个题,我只会套模板导致做的太慢当时没......
  • 2019年9月22日总结
    题没有落下,比赛也没有落下,感觉自己手感已经上来了,我们商量了一下决定不去银川了,虽然银川拿牌的几率是最大的,不过还是抵制一波。线段树的各种题也看的差不多了,接下来看并查集......
  • 2019年8月26日训练日记
    今天主要是看了STL和并查集,因为STL也是一种最基础的数据结构,并查集以前就以为只能处理团体关系的问题,今天看了这些题,很多都是和其他知识点结合起来了,和背包,二分。不过主体思......