利用贪心策略求解背包问题

描述

给定一个载重量为M的背包,考虑n个物品,其中第i个物品的重量 ,价值wi (1≤i≤n),要求把物品装满背包,且使背包内的物品价值最大。

有两类背包问题(根据物品是否可以分割),如果物品不可以分割,称为0—1背包问题(动态规划);如果物品可以分割,则称为背包问题(贪心算法)。

分析

在这里插入图片描述
有3种方法来选取物品:
(1)当作0—1背包问题,用动态规划算法,获得最优值220;
(2)当作0—1背包问题,用贪心算法,按性价比从高到底顺序选取物品,获得最优值160。由于物品不可分割,剩下的空间白白浪费。
(3)当作背包问题,用贪心算法,按性价比从高到底的顺序选取物品,获得最优值240。由于物品可以分割,剩下的空间装入物品3的一部分,而获得了更好的性能。

在这里插入图片描述
注意:贪心策略实现思想较简单,但是对于某些问题可能求解出来的并不是最优解

代码

仅求最优值

#include<iostream>
#include<algorithm>
using namespace std;

struct bag
{
    int w;
    int v;
    double c;
} a[1001];

bool cmp(bag a,bag b)
{
    return a.c >= b.c;
}

double knapsack(int n, bag a[], double c)
{
    double cleft = c;
    int i = 0;
    double b = 0;
    while(i<n && a[i].w<cleft)
    {
        cleft -= a[i].w;
        b += a[i].v;
        i++;
    }
    if (i<n)
        b += 1.0*a[i].v*cleft/a[i].w;
    return b;
}

int main()
{
    int c;
    int n;
    int i;
    while(cin>>c>>n)
        && c)
    {
        for(i=0; i<n; i++)
        {
            cin>>a[i].w>>a[i].v);
            a[i].c = 1.0*a[i].v/a[i].w;
        }
        sort(a, a+n, cmp);
        cout<<knapsack(n,a,c);
    }
    return 0;
}

求解向量

#include<iostream>
#include<algorithm>
using namespace std;

struct bag
{
    int w;
    int v;
    double x;
    int index;
    double c;
} a[1001];

bool cmp(bag a,bag b)
{
    if(a.c >b.c)
        return true;
    return false;
}

double knapsack(int n, bag a[], double c)
{
    double cleft = c;
    int i = 0;
    double b = 0;
    while(i<n && a[i].w<=cleft)
    {
        cleft -= a[i].w;
        b += a[i].v;
        a[a[i].index].x = 1.0;
        i++;
    }
    if (i<n)
    {
        a[a[i].index].x = 1.0*cleft/a[i].w;
        b += a[a[i].index].x*a[i].v;
    }
    return b;
}

int main()
{
    int c;
    int n;
    int i;
    while(cin>>c>>n && c)
    {
        for(i=0; i<n; i++)
        {
            cin>>a[i].w>>a[i].v;
            a[i].c = 1.0*a[i].v/a[i].w;
            a[i].x = 0;
            a[i].index = i;
        }
        sort(a, a+n, cmp);
        knapsack(n,a,c);
        cout<<knapsack(n,a,c);
        for(i=0; i<n; i++)
            if (a[i].x==0)
                cout<<"0 ";
            else if (a[i].x==1)
                cout<<"1 ";
            else
                cout<< a[i].x;
        cout<<endl;
    }
    return 0;
}


猜你喜欢

转载自blog.csdn.net/qq_45654306/article/details/105538704