背包问题,贪心法

#include <bits/stdc++.h>

using namespace std;

struct Node {
    //物品的重量,价值,单位价值,取值比例
    double w, v, signalValue, prop;
    int id;//编号
};

bool cmp(Node a, Node b) {
    return a.signalValue > b.signalValue;
}

bool cmp1(Node a, Node b) {
    return a.id < b.id;
}

int main() {
    int n;
    double maxWeight;
    //物品数量,背包最大重量
    scanf("%d%lf", &n, &maxWeight);
    Node obj[n];

    //录入数据
    for (int i = 0; i < n; i++) {
        scanf("%lf%lf", &obj[i].w, &obj[i].v);
        obj[i].signalValue = obj[i].v / obj[i].w;
        obj[i].id = i;
        obj[i].prop = 0;
    }

    sort(obj, obj + n, cmp);

    //背包当前已经存储的重量和积累价值
    double nowW = 0, nowV = 0;
    for (int i = 0; i < n; i++) {
        //前面已经按物品的单位价值从大到小排序
        //遍历每件物品
        //当前背包容量可以装下当前物品
        if (maxWeight >= obj[i].w) {
            obj[i].prop = 1;
            maxWeight -= obj[i].w;
            nowW += obj[i].w;
            nowV += obj[i].v;
        } else {
            //当前背包容量不能把当前物品全部装下
            nowV += obj[i].signalValue * maxWeight;
            nowW += maxWeight;
            obj[i].prop = maxWeight / obj[i].w;
            maxWeight = 0;
        }
    }

    printf("当前背包重量: %.2f\n当前背包价值: %.2f\n", nowW, nowV);

    //打印每件物品的取值比例
    sort(obj, obj + n, cmp1);
    for (int i = 0; i < n; i++)
        printf("第%d件物品取值: %.4f\n", i + 1, obj[i].prop);
    return 0;
}

01背包问题是指有一个容量为V的背包,有n个物品,每个物品的重量为w[i],价值为v[i],问如何选择物品放入背包使得背包中物品的总价值最大,其中每个物品要么选中要么不选中。 贪心法是一种不保证得到最优解的方法,但是可以在很短的时间内得到一个较好的解。对于01背包问题,可以采用贪心策略:将每个物品的单位重量价值(即 v[i]/w[i])从大到小排序,然后依次将单位重量价值最大的物品放入背包中,直到背包无法再放下任何一个物品为止。 以下是贪心法的代码实现: ```python def knapsack_greedy(capacity, weights, values): n = len(weights) unit_values = [(values[i] / weights[i], i) for i in range(n)] unit_values.sort(reverse=True) total_value = 0 for unit_value, i in unit_values: if capacity >= weights[i]: total_value += values[i] capacity -= weights[i] else: total_value += unit_value * capacity break return total_value ``` 其中,unit_values 是一个元组列表,每个元组包含物品的单位重量价值和该物品的下标。排序时按照单位重量价值从大到小排序,然后依次将物品放入背包中,直到背包放不下为止。最后返回背包中物品的总价值。 需要注意的是,这种贪心策略并不一定能够得到最优解。当物品的重量和价值差别很大时,这种贪心策略可能会得到一个很差的解。因此,在实际应用中需要根据具体情况选择合适的算法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值