1268:【例9.12】完全背包问题

【题目描述】
设有n种物品,每种物品有一个重量及一个价值。但每种物品的数量是无限的,同时有一个背包,最大载重量为M,今从n种物品中选取若干件(同一种物品可以多次选取),使其重量的和小于等于M,而价值的和为最大。

【输入】
第一行:两个整数,M(背包容量,M≤200)和N(物品数量,N≤30);

第2…N+1行:每行二个整数Wi,Ci,表示每个物品的重量和价值。

【输出】
仅一行,一个数,表示最大总价值。

【输入样例】
10 4
2 1
3 3
4 5
7 9
【输出样例】
max=12
【来源】

No

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
const int maxn = 205;
using namespace std;
int w[maxn],c[maxn],dp[maxn];
int main(){
	int V,N;
	cin>>V>>N;
	for(int i=1;i<=N;i++) cin>>w[i]>>c[i];
	for(int i=1;i<=N;i++){
		for(int v=w[i];v<=V;v++){
			dp[v] = max(dp[v] , dp[v-w[i]] + c[i]);
		}
	}
	cout<<"max="<<dp[V];
	return 0;
} 

完全背包模板题,和01背包的却别就是一个是顺序取,一个是逆序取。
比如取第i个物品时
01背包是每一样只能取一个,所以取的时候考虑的是i-1的情况
完全背包是每一样都能无限取,所以考虑的i的情况

这两种不同的考虑就决定你滚动数组的取值顺序

01背包
1.dp[i-1][v] 不取i
2.dp[i-1][v-w[i]]+c[i] 取i
因为v > v-w[i] 你考虑的是i-1的情况,所以i-1前面的值是一定不能变的,简单点说i的情况只和i的正上方和左上方有关(i-1),因为是一维数组,后面的不影响前面的,后面更新的是i的情况

完全背包
1.dp[i-1][v] 不取i
2.dp[i][v-w[i]]+c[i] 取i
和01差不都,关键是取i的时候不一样,因为转换到一直取i的情况,而i的情况只和正上方和他自己这行的左边有关,你只有先把自己的左边求了才能从左往右求,
我这没有图片,算法笔记P446页有,图片一目了然
总之,01背包是根据i-1行的左侧从右向左把i-1跟新成i
完全背包则是根据自己的这一行从左往右生成i的 ( 正上方的i-1)

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值