完全背包基础 & 与01背包的区别

0.提示:学习多重背包之前最好先学习01背包!!

   推荐:https://blog.csdn.net/2302_79433723/article/details/135018316?ops_request_misc=%257B%2522request%255Fid%2522%253A%252222EDEB54-6C1D-4D63-B495-6ABAB00BEC75%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=22EDEB54-6C1D-4D63-B495-6ABAB00BEC75&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-2-135018316-null-null.142^v100^pc_search_result_base5&utm_term=01%E8%83%8C%E5%8C%85%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B&spm=1018.2226.3001.4187

1.完全背包的定义

完全背包是研究这样一种问题:有n个物体,每个物体的大小为w,价值为v,每个物体都有 无数个,要把他们装进一个大小为t的背包,使价值最大化。

(注意:01背包的物体数只有一个,不要把他们搞混了)

 

2.贪心是否可以得到最优解?

     不可以,例如:

参见我的另一篇文章:(卡价值贪心)https://blog.csdn.net/luogu_hezhenmin1/article/details/142673321?spm=1001.2014.3001.5501m

    又比如:

有3个物体,背包大小为10

w1=6,v1=1;

w2=4,v2=8;

w3=10,v3=10;

贪心会选第一个第二个,但选第3个价值更大(卡性价比贪心)

结论:贪心不可以求得最优解

3.如何求解?

 3.1如果选择第j个物体,且i>=j,那么

dp[i]=dp[i-w[j]]+v[j];//如果选择第j个物体

      3.2如果不选择第j个物体,那么

dp[i]=dp[i];//不选

     3.3那么最大价值就是

dp[i]=max(dp[i],dp[i-w[i]]+v[i]);

看到这里,有人就会发问了:这不是跟01背包一样吗?

说的没错,完全背包的状态转移方程跟01背包一样,但是在01背包的学习中,为了防止一个物体多次选择,所以我们的第二重循环是倒序枚举,为的就是防止dp[j-w[i]]在dp[j]之前就已经状态转移了,现在我们的第二重循环是正序枚举,所以只要j-w[i]>=w[i],那么dp[j]就有可能会等于dp[j-2*w[i]]+2*v[i],以此类推。

4.完全背包的例题与代码

    洛谷P1616

抽象为:有n(n<=1e4)个物体,每个物体的大小为w(w<=1e4),价值为v(v<=1e4),每个物体都有 无数个,要把他们装进一个大小为t(t<=1e7)的背包,使价值最大化。

代码:

#include<bits/stdc++.h>
using namespace std;
int t,m;
long long dp[10000002];
int v[1000002],w[1000002];
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
	cin>>t>>m;
	for(int i=1;i<=m;i++)
	    cin>>v[i]>>w[i];
	for(int i=1;i<=m;i++)
		for(int j=v[i];j<=t;j++)
			dp[j]=max(dp[j],dp[j-v[i]]+w[i]);
	cout<<dp[t];
	return 0;
}

注意:十年OI一场空,不开long long 见祖宗!!!

例题:hdu  

 P1734   P2722

5.几句闲话

 背包计数问题的状态转移方程是dp[i]+=dp[i-w[i]];

                                                              谢谢

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值