您的位置:首页 > 其它

完全背包问题

2018-02-03 23:06 162 查看
完全背包问题

题目 :

有N种物品和一个容量为V的背包,每种物品都有无限件可用。第i种物品的费用是c[i],价值是w[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。

算法分析:

此题跟01背包相似,所不同的是物品无无限件,考虑到第i种物品最多选V/c[i]件,于是可以把第i种物品转化为V/c[i]件费用及价值均不变的物品,然后求解这个01背包问题。

状态转移方程:f[i][v]=max{f[i-1][v-K*c[i]]+k*w[i]|k*c[i]<=v}

伪码:

              for i=1..N

                     for v=0..V

                            f[v]=max{f[v],f[v-c[i]]+w[i]}

注意:此处v的循环次序和01背包的循环次序不同!!!

原因:01背包发f[i][v]是根据状态发f[i-1][v-c[i]]递推过来的,而现在完全背包每件物品可选无限件,所以在考虑“加选一件第i种物品”的策略时,却正需要已选入第i个物品子结果发f[i][v-c[i]]。

简单优化:

1)若两件物品i、j满足c[i]<=c[j]    并且w[i]>=w[j],则将物品j去掉,不用考虑 .

2)将费用大于V的物品去掉 .

 

 

实现代码:

#include<bits/stdc++.h>
using namespace std;
struct goods
{
int c,w; //c为价钱,w为价值
}goods[10000];
int main()
{
int n,v,i,j;
int f[1000];
cin>>n>>v; //n为物品数,v为价钱容量
for(i=0;i<=v;i++) //背包不要求装满
f[i]=0;
for(i=0;i<n;i++)
cin>>goods[i].c>>goods[i].w;
for(i=0;i<n;i++)
{
for(j=goods[i].c;j<=v;j++)
if(f[j]<f[j-goods[i].c]+goods[i].w) //重要条件
f[j]=f[j-goods[i].c]+goods[i].w;

}
cout<<f[v]<<endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: