背包问题总结第一讲——可拆分背包
2009-04-30 03:56 Logic0 阅读(539) 评论(0) 编辑 收藏 举报题目:
有N件物品和一个容量为V的背包。第i件物品占空间c[i],价值是w[i],物品可拆分,求解将哪些物品装入背包可使价值总和最大。
基本思路:
因为物品可拆分,故为了使整个背包内物品的总价值最大,可按照物品单位价值,依次从大到小装入,使背包的每份空间的价值尽可能大。
类型:
贪心算法。策略:按物品单位价值降序依次装入,直至物品剩余为0,或背包剩余空间为0。
代码:
#include <iostream>
#include <vector>
#include <algorithm>
#define MAX 100
using namespace std;
typedef struct
{
int c,v;
float pj;
}NODE;
bool compare(NODE a,NODE b)
{
return a.pj>b.pj;
}
int main()
{
vector<NODE> p;
int bag_v;
float result = 0.0;
int i,j,n;
cin>>n; //number of cases
while(n--)
{
cin>>bag_v; //v of the bag
cin>>i; //number of things
NODE tmp;
for(j=1 ; j<=i ; j++)
{
cin>>tmp.c>>tmp.v;
tmp.pj = (float)tmp.v/tmp.c;
p.push_back(tmp);
}
sort(p.begin(),p.end(),compare);
vector<NODE>::iterator i = p.begin();
while(i!=p.end() && bag_v>0)
{
if(bag_v >= (*i).c)
{
result += (*i).v;
bag_v -= (*i).c;
}
else
{
result += (*i).pj * bag_v;
bag_v = 0;
}
i++;
}
cout<<"max value is "<<result<<endl;
}
return 0;
}
贪心算法的应用,也是背包中最简单的一个。
举例应用:
1.有开放时间区间为[s,e]的会议室,现有N个会议,分别需要用会议室的时间段为[a1,b1],[a2,b2],[a3,b3],...,[an,bn]。
求最多可以举行多少个会议。
2.有存储空间为S的一盒磁盘,现有N个文件需要存入,文件i的大小为a[i],问最多可以存多少个文件。