acwing 1024. 装箱问题/01背包

题目传送门

题目描述

有一个箱子容量为 V,同时有 n 个物品,每个物品有一个体积(正整数)。

要求 n 个物品中,任取若干个装入箱内,使箱子的剩余空间为最小。

输入格式

第一行是一个整数 V,表示箱子容量。

第二行是一个整数 n,表示物品数。

接下来 n 行,每行一个正整数(不超过10000),分别表示这 n 个物品的各自体积。

输出格式

一个整数,表示箱子剩余空间。

数据范围

0<V≤20000
0<n≤30

输入样例:

24
6
8
3
12
7
9
7

输出样例:

0

01背包

分析

体积不超过m的情况下的最大体积是多少

所以就是01背包中,将体积也看成价值,问总体积不超过m的情况下总价值(总体积)最大是多少

f[i][j] = max(f[i-1][j], f[i][j-v[i]] + v[i])

  • f[i-1][j]表示不选第i件物品
  • f[i][j-v[i]] + v[i]表示当体积j大于等于v[i]的时候,选择第i件物品

代码

二维:

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int f[40][20010];
int v[40];
int main()
{
	int m, n;
	cin >> m;
	cin >> n;
	for(int i = 1; i <= n; i++) cin >> v[i];
	
	for(int i = 1; i <= n; i++)
	{
		for(int j = 0; j <= m; j++)
		{
			f[i][j] = f[i-1][j];
			if(j >= v[i]) f[i][j] = max(f[i][j], f[i-1][j-v[i]] + v[i]);
		}
	}	
	cout << m - f[n][m] << endl;
	return 0; 
} 

一维:

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int f[20010];
int v[40];
int main()
{
	int  n, m;
	cin >> m >> n;
	
	for(int i = 1; i <= n; i++) cin >> v[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]] + v[i]);
		}
	}	
	cout << m - f[m] << endl;
	return 0; 
} 

时间复杂度

参考文章

posted @ 2022-03-13 08:30  VanHope  阅读(58)  评论(0编辑  收藏  举报