完全背包精讲

本文介绍了完全背包问题的定义,与01背包问题的区别,以及使用动态规划求解的二维和一维优化代码实例。重点在于状态转移方程和两种代码版本的对比分析。
摘要由CSDN通过智能技术生成

完全背包例题

题目描述

有 n 件物品和一个容量是 m 的背包。每件物品都可以使用无数次

第 i 件物品的体积是 vi​,价值是 wi​。

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

输入描述

第一行两个整数,n,m,用空格隔开,分别表示物品数量和背包容积。

接下来有 n 行,每行两个整数 vi​,wi​,用空格隔开,分别表示第 i 件物品的体积和价值。

0<n,m≤1000

0<vi​,wi​≤1000

输出描述

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

样例输入 1 

4 5
1 2
2 4
3 4
4 5

样例输出 1 

10

完全背包问题和01背包问题很相似。
01背包问题每个物品只能选一个,而完全背包问题每个物品可以选无限次

DP问题的关键是找到状态转移方程:

1.状态函数f[i][j]表示第i件物品容量为j最大价值

2.f[i][j]=max(f[i-1][j],f[i][j-w[i]]+v[i]);装得下分为两种情况1.装 2.不装  同时注意是与f[i][j-w[i]]+v[i]比较而不是i

一.二维代码
#include <bits/stdc++.h>
using namespace std;
int f[100][100];//状态函数f[i][j]表示第i件物品容量为j最大价值
int v[100]; 
int w[100];
/*
函数功能:求完全背包 
函数形参:物品数量和背包容量
函数返回值:返回最大值 
*/  
int fun(int n,int m)
{
	for(int i=1;i<=n;i++) //物品 
	{
		for(int j=1;j<=m;j++) //容量 
		{
			if(j<w[i]) //装不下 
				f[i][j]=f[i-1][j]; //就等于i-1件物品容量等于j时候的价值 
			else
				f[i][j]=max(f[i-1][j],f[i][j-w[i]]+v[i]);//装得下分为两种情况1.装 2.不装  同时注意是与f[i][j-w[i]]+v[i]比较而不是i
		}
	}
		return f[n][m];
}
int main()
{
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=n;i++)
		cin>>w[i]>>v[i];
	cout<<fun(n,m);
    system("pause");
	return 0;
}
二.一维优化代码
#include <iostream>
using namespace std;
 
const int N=1010;
int v[N],w[N],f[N];
int n,m;
 
int main()
{
  scanf("%d%d",&n,&m);  
  for(int i = 1;i <= n;i++){
      scanf("%d%d",&v[i],&w[i]);
  } 
  for(int i=1;i<=n;i++)
    for(int j=v[i];j<=m;j++){
        f[j]=max(f[j],f[j-v[i]]+w[i]);//一维优化之后与01背包优化类似
    }    
  printf("%d",f[m]);  
  return 0;
}

 解决完全背包!

关注我,带你入坑下一个多重背包!

  • 10
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值