代码改变世界

背包问题总结第一讲——可拆分背包

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],问最多可以存多少个文件。