【程序设计竞赛算法】背包问题——贪心法

这篇具有很好参考价值的文章主要介绍了【程序设计竞赛算法】背包问题——贪心法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

【程序设计竞赛算法】背包问题——贪心法

贪心算法是一种基于贪心策略的算法,它在每一步选择中都采取当前状态下的最优选择,以期望最终达到全局最优解。

背包问题是一个经典的组合优化问题,可以分为 0-1 背包问题和分数背包问题。其中,0-1 背包问题要求物品只能选择一次,而分数背包问题允许物品被选择多次。

贪心算法解决背包问题的原理如下:

1、对于 0-1 背包问题,贪心算法的思路是优先选择单位价值最高的物品放入背包中。即计算每个物品的单位价值(价值与重量的比值),然后按照单位价值从高到低进行排序。接着,从单位价值最高的物品开始,依次尝试将物品放入背包中,如果放入会超过背包容量,则跳过该物品;否则,将物品放入背包,并更新背包容量和总价值。重复这个过程,直到背包容量为 0 或所有物品都被考虑完毕。

2、对于分数背包问题,贪心算法的思路是优先选择单位价值最高的物品放入背包中,直到背包容量为 0 或所有物品都被考虑完毕。与 0-1 背包问题不同的是,分数背包问题允许物品被选择多次,因此可以按照单位价值从高到低进行排序后,依次选择整个物品或者部分物品放入背包,直到背包容量为 0。

下面是使用 C 语言给出一个贪心算法解决 0-1 背包问题的具体例子:

#include <stdio.h>
#include <stdlib.h>

// 物品结构体
typedef struct {
    int weight; // 重量
    int value;  // 价值
} Item;

// 比较函数,用于按照单位价值从高到低排序
int compare(const void* a, const void* b) {
    Item* item1 = (Item*)a;
    Item* item2 = (Item*)b;
    double ratio1 = (double)item1->value / item1->weight;
    double ratio2 = (double)item2->value / item2->weight;
    if (ratio1 < ratio2) {
        return 1; // 比例大的在前
    } else if (ratio1 > ratio2) {
        return -1; // 比例小的在后
    } else {
        return 0;
    }
}

// 贪心算法解决 0-1 背包问题
double knapsack(Item items[], int n, int capacity) {
    qsort(items, n, sizeof(Item), compare); // 按照单位价值从高到低排序
    
    double totalValue = 0.0; // 总价值
    int currentWeight = 0; // 当前背包重量
    
    for (int i = 0; i < n; i++) {
        if (currentWeight + items[i].weight <= capacity) {
            // 如果当前物品可以完整放入背包
            currentWeight += items[i].weight;
            totalValue += items[i].value;
        } else {
            // 如果当前物品只能放入部分
            int remainingCapacity = capacity - currentWeight;
            double fraction = (double)remainingCapacity / items[i].weight;
            currentWeight += remainingCapacity;
            totalValue += items[i].value * fraction;
            break;
        }
    }
    
    return totalValue;
}

int main() {
    Item items[] = {
        {10, 60},
        {20, 100},
        {30, 120}
    };
    int n = sizeof(items) / sizeof(items[0]);
    int capacity = 50;
    
    double maxValue = knapsack(items, n, capacity);
    printf("背包中物品的最大总价值:%lf\n", maxValue);

    return 0;
}

在上述代码中,我们首先定义了一个物品结构体 Item,包含物品的重量和价值。然后,我们定义了一个比较函数 compare,用于按照单位价值从高到低排序物品。

在 knapsack 函数中,我们首先调用 qsort 函数对物品数组 items[] 按照单位价值从高到低进行排序。接着,我们使用贪心策略,从单位价值最高的物品开始,尝试将物品放入背包中。如果物品可以完整放入背包,则将物品的重量加入当前背包重量,并将物品的价值加入总价值。如果物品只能放入部分,则计算出可以放入的部分重量,更新当前背包重量和总价值,并终止循环。

在 main 函数中,我们给定了一组物品的重量和价值,并设置背包容量为 50。通过调用 knapsack 函数,得到背包中物品的最大总价值,并输出结果。

需要注意的是,贪心算法解决背包问题的结果不一定是最优解。在一般情况下,贪心算法无法保证得到全局最优解,因为它只考虑了局部最优情况。对于一些特殊情况的背包问题,贪心算法可能得到最优解,但对于一般的背包问题,通常需要使用动态规划等其他方法来获得最优解。文章来源地址https://www.toymoban.com/news/detail-776149.html

到了这里,关于【程序设计竞赛算法】背包问题——贪心法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 贪心算法解决背包问题和动态规划解决0-1背包问题(c语言)

    运行结果如下: 运行结果如下: 总结: 贪心算法: 每一步都做出当时看起来最佳的选择,也就是说,它总是做出局部最优的选择。 贪心算法的设计步骤: 对其作出一个选择后,只剩下一个子问题需要求解。 证明做出贪心选择后,原问题总是存在最优解,即贪心选择总是安

    2024年02月04日
    浏览(53)
  • 背包问题算法全解析:动态规划和贪心算法详解

    计算机背包问题是动态规划算法中的经典问题。本文将从理论和实践两个方面深入探讨计算机背包问题,并通过实际案例分析,帮助读者更好地理解和应用该问题。 背包问题是一种经典的优化问题。有的时候我们需要将有一堆不同重量或者体积的物品放入背包,但是背包容量

    2024年02月09日
    浏览(49)
  • 【趣学算法】Day3 贪心算法——背包问题

    14天阅读挑战赛 努力是为了不平庸~ 算法学习有些时候是枯燥的,这一次,让我们先人一步,趣学算法!  ❤️一名热爱Java的大一学生,希望与各位大佬共同学习进步❤️ 🧑个人主页:@周小末天天开心 各位大佬的点赞👍 收藏⭐ 关注✅,是本人学习的最大动力 感谢! 📕该

    2024年02月02日
    浏览(43)
  • c++—0/1背包问题--贪心算法(详解)

    贪心算法的基本思想 •贪心算法的特点是每个阶段所作的选择都是局部最优的,它期望通过所作的局部最优选择产生出一个全局最优解。 贪心与动态规划: 与动态规划不同的是,贪心是 鼠目寸光 ; 动态规划是 统揽全局 。 贪心:每个阶段产生的都是局部最优解 贪心算法的

    2024年02月04日
    浏览(41)
  • (C语言贪心算法)0/1背包问题

    已知一个载重为M的背包和n件物品,物品编号从0到n-1。第i件物品的重量为 wi,若将第i种物品装入背包将获益pi,这里,wi0,pi0,0=in。所谓0/1背包问题是指在物品不能分割,只能整件装入背包或不装入的情况下,求一种最佳装载方案使得总收益最大。 第 1 行中有 2 个正整

    2024年02月08日
    浏览(40)
  • java实现0-1背包问题方案(动态规划-贪心算法-回溯-分支定界)

    动态规划算法时间复杂度较低,能够求解较大规模的问题,但空间复杂度较高,不适用于数据量较大的问题。 贪心算法时间复杂度较低,能够求解较大规模的问题,但不能保证求得的解是最优解。 回溯算法能够求解较小规模的问题,但时间复杂度较高,不适用于数据量较大

    2024年02月01日
    浏览(121)
  • 2022 年辽宁省大学生程序设计竞赛 个人题解

    title : 2022 年辽宁省大学生程序设计竞赛 date : 2022-10-25 tags : ACM,练习记录 author : Linno 题目链接:https://ac.nowcoder.com/acm/contest/43937 进度:10/13 质量比较差的场,后三题是错的,D题spj也是错的,其他nt题也多。 A-伟大奋斗 B-可莉的五子棋 枚举每个点作为起点向下统计就行了。 C-消

    2023年04月08日
    浏览(45)
  • 2019湖南省大学生程序设计竞赛题解(D)

    很妙的类似区间dp, 我自己是想不到,本题解题思路来自学长的博客: 长沙橘子猫 题意 有一个长度为 n n n 的序列,你可以给每个位置填 0 ∼ 9 0sim9 0 ∼ 9 的一个数,有 m m m 个限制,每个限制 [ l i , r i ] [l_{i}, r_{i}] [ l i ​ , r i ​ ] 要求区间内的数相乘必须为 9 9 9 的倍数,问

    2023年04月15日
    浏览(58)
  • 2023年四川大学生程序设计竞赛-K.倒转乾坤

    Cuber QQ 现在手上有两个圆环,其中小圆环的直径是 d,大圆环的直径是 2d 。他将小圆环放在大圆环内, 并让小圆环紧贴大圆环内壁进行无滑动的滚动。   Cuber QQ 总是喜欢动态的美,他在小圆环上等间隔地标记了 n 个点,他想知道在小圆环贴着大圆环运动一周后,他所

    2024年02月16日
    浏览(59)
  • 2023 年第五届河南省 CCPC 大学生程序设计竞赛

    Problem A. 小水獭游河南 ∣ a ∣ ≤ ∣ Σ ∣ = 26 ,暴力枚举 a 判断 b 是否为是回文串即可,时间复杂度 O ( ∣ Σ ∣ ∣ s ∣ ) 。 |a| ≤ |Σ| = 26,暴力枚举 a 判断 b 是否为是回文串即可,时间复杂度 O(|Σ||s|)。 ∣ a ∣ ≤ ∣Σ∣ = 26 ,暴力枚举 a 判断 b 是否为是回文串即可,时间复

    2024年02月03日
    浏览(83)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包