[蓝桥杯][算法训练] ALGO-21 VIP试题 装箱问题 【动态规划】01背包问题

ALGO-21 VIP试题 装箱问题 动态规划

资源限制
时间限制:1.0s 内存限制:256.0MB

问题描述
  有一个箱子容量为V(正整数,0<=V<=20000),同时有n个物品(0<n<=30),每个物品有一个体积(正整数)。
  要求n个物品中,任取若干个装入箱内,使箱子的剩余空间为最小。
输入格式
  第一行为一个整数,表示箱子容量;
  第二行为一个整数,表示有n个物品;
  接下来n行,每行一个整数表示这n个物品的各自体积。
  
输出格式
  一个整数,表示箱子剩余空间。
  样例输入
  24
  6
  8
  3
  12
  7
  9
  7
样例输出
0

题解:

动态规划之01背包问题

1.状态表示 f:(化零为整的过程)

集合 f ( i , j ) f(i,j) f(i,j)——取前i个物品,且体积不超过j的方案 的集合
属性(使集合中每个方案的总体积最大): m a x ( f ( N , V ) ) max (f(N,V)) max(f(N,V))——最大体积 (只考虑前N个物品,且总体积不超过 V)

2.状态计算(集合划分:化整为零的过程):

对于每一个物体,都有两种选择:放入或者不放入
集合1:不放第i个的总体积值 : f ( i − 1 , j ) f(i-1,j) f(i1,j)
集合2:放第i个的总体积值: f ( i − 1 , j − w i ) + w i f(i-1,j-w_i)+w_i f(i1,jwi)+wi

C++示例代码:

#include
#include
using namespace std;
int Wi[30];//每个物品的体积 
int f[33][20021];//取前i个物品,且总体积<=j的 体积
int main(){
     
	int V,N;
	cin>>V>>N;
	for(int i=1;i<=N;i++){
     
		cin>>Wi[i];
	}
/*
	1.状态表示 f:(化零为整的过程) 
	集合: f(i,j)取前i个物品,且体积不超过j的方案 的集合 
	属性:(使集合中每个方案的总体积最大):max f(N,V)最大体积 (只考虑前N个物品,且总体积不超过 V)
	
	2.状态计算(集合划分:化整为零的过程):
	对于每一个物体,都有两种选择-放入或者不放入
	集合1:不放第i个的体积值 :f(i-1,j) 
	集合2:放第i个的体积值:f(i-1,j-wi)+wi
*/
	for(int i=1;i<=N;i++){
     //  1
		for(int j=0;j<=V;j++){
     
			f[i][j]=f[i-1][j];//不选的集合
			if(Wi[i]<=j)//选 的集合不一定存在 ,要保证W[i]体积不超过j才能考虑
				f[i][j]=max(f[i][j],f[i-1][j-Wi[i]]+Wi[i]);
		}
	}
	cout<<V-f[N][V];//总体积-最大体积 
	
	return 0;
}

你可能感兴趣的:(动态规划,蓝桥)