首页 > 其他分享 >《分数背包问题》快速求解(贪心法)

《分数背包问题》快速求解(贪心法)

时间:2024-05-23 23:29:49浏览次数:21  
标签:分数 背包 capacity weight items value 贪心

目录

前言

一、贪心策略

二、具体步骤

实例如下:

三、代码实现

伪代码:

C++代码:

 

        总结


前言

分数背包问题:

在分数背包问题中,物品可以被分割成更小的部分,可以部分装入背包,而不是只能选择整个物品装入或不装入背包。


一、贪心策略

贪心法在解决分数背包问题时,可以按照 单位重量价值(价值/重量)从大到小的顺序,依次将单位重量价值最大的物品放入背包,直到背包装满为止。这样能够得到一个最优解。

二、具体步骤

  1. 计算每个物品的单位重量价值(value/weight)类似于 性价比的意思(不是屌丝饮料哦~)。
  2. 按照单位重量价值从大到小排序。
  3. 依次将单位重量价值最大的物品放入背包,直到背包无法再放入为止。

实例如下:

这里按照性价比排序:2.1  、2  、1.5  、1.2  、1   

总重量=30+10+20+40=100(这里最后一样物品取4/5)

总价值=65+20+30+48=163

三、代码实现

伪代码:

FractionalKnapsack(values[], weights[], capacity):
    n = length of values[] and weights[]
    
    // 计算每个物品的单位重量价值
    for i from 0 to n-1:
        value_per_weight[i] = values[i] / weights[i]
    
    // 按单位重量价值从大到小排序
    sort items by value_per_weight in descending order
    
    total_value = 0
    remaining_capacity = capacity
    
    // 尝试将物品放入背包
    for i from 0 to n-1:
        if weights[i] <= remaining_capacity:
            total_value = total_value + values[i]
            remaining_capacity = remaining_capacity - weights[i]
        else:
            total_value = total_value + value_per_weight[i] * remaining_capacity
            break
    
    return total_value

C++代码:

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

struct Item {
    int value;
    int weight;
    double value_per_weight;
};

bool compare(Item a, Item b) {
    return a.value_per_weight > b.value_per_weight;
}

double fractional_knapsack(vector<int> value, vector<int> weight, int capacity) {
    vector<Item> items;
    for (int i = 0; i < value.size(); i++) {
        items.push_back({value[i], weight[i], (double)value[i]/weight[i]});
    }

    sort(items.begin(), items.end(), compare);

    double total_value = 0.0;
    int remaining_capacity = capacity;

    for (int i = 0; i < items.size(); i++) {
        if (remaining_capacity >= items[i].weight) {
            total_value += items[i].value;
            remaining_capacity -= items[i].weight;
        } else {
            total_value += items[i].value_per_weight * remaining_capacity;
            break;
        }
    }

    return total_value;
}

int main() {
    vector<int> value = {60, 100, 120};
    vector<int> weight = {10, 20, 30};
    int capacity = 50;

    cout << fractional_knapsack(value, weight, capacity) << endl; // 输出为240.0

    return 0;
}
   结果:(这里我写的性价比分别是 60,50,40 可以根据要求自我修改)

总结:

贪心算法在解决背包问题时具有以下优点和缺点:

优点:
1. 算法简单易懂:贪心算法通常实现简单,易于理解和实现。
2. 时间复杂度低:贪心算法通常具有较低的时间复杂度,适用于大部分实际问题的求解。
3. 快速得到一个近似解:贪心算法能够在较短时间内得到一个较好的近似解,对于一些实际问题来说已经可以满足要求。

缺点:
1. 不能保证得到最优解:贪心算法的局部最优策略不一定能够达到全局最优解,因此无法保证对所有问题都能够得到最优解。
2. 可能存在局部最优解误判:贪心算法可能会因为贪心选择而导致达到一个局部最优解,但最终并不是整体最优解。
3. 需要正确的贪心选择策略:贪心算法对于不同的问题需要选择合适的贪心策略,否则可能会得到错误的结果。

综上所述,贪心算法在背包问题中有其优势和局限性,具体是否选择使用贪心算法取决于问题本身的特点和要求。在实际应用中,需要仔细考虑问题的具体情况,综合考虑算法的优势和局限性,选择合适的解决方法。
 

标签:分数,背包,capacity,weight,items,value,贪心
From: https://blog.csdn.net/2301_79582459/article/details/139159440

相关文章

  • SCAU 18705 01背包问题
    18705 01背包问题时间限制:1000MS 代码长度限制:10KB题型:编程题   语言:不限定Description有一个容积为M的背包和N件物品。第i件物品的体积W[i],价值是C[i]。求解将哪些物品装入背包可使价值总和最大。每种物品只有一件,可以选择放或者不放入背包。输入格式第一......
  • Codeforces Round 946 (Div. 3) G Money Buys Less Happiness Now(反悔贪心)
    MoneyBuysLessHappinessNow1.题目大意:有n天,每天可以赚x块钱,然后每天可以通过花\(C_{i}\)块钱购买1点快乐值,然后每天赚的钱至少要在下一天才能用,问最多能获得多少快乐值。2.解题思路:我们发现天数变得很多,不能像e题那样dp了,所以要用贪心。具体来讲,我们碰到当前能买的就直接......
  • 背包dp
    P1064[NOIP2006提高组]金明的预算方案思路:有依赖的背包。主要的问题和解决方案,见代码注释.#include<bits/stdc++.h>usingnamespacestd;#defineintlonglong#defineendl"\n"constintN=2e5+10;typedefstructnode{intp,w,typ;}node;boolcmp(nodea,n......
  • 【CodeChef】Change A to B(贪心)
    题目大意:每次操作可以使\(a\)变成\(a+1\)或\(a\cdotk\),问将\(a\)变成\(b\)最少需要几次操作。将题目等价转化为,将\(b\)变成\(a\)最少需要几次以下操作:操作1:将\(b\)变成\(b-1\)。操作2:如果\(b\)能被\(k\)整除,将b变成\(\frac{b}{k}\)。考虑贪心,当能够使用操作2时优先使用操作......
  • 记录一个批量拆分数据粘贴到各个表里的小脚本
    importosimporttkinterastkimporttkinter.filedialogfromtkinterimportttkimporttkinter.messageboxfromtkinterimportscrolledtextimportxlwingsasxwfrompandasimportExcelFilefrompandasimportread_excelglobaldf_total,cbox_sheet_ori,cbo......
  • 2022-06-30-和讯网上市公司社会责任综合评分数据
    和讯网发布的我国上市公司社会责任综合评分作为企业社会责任表现的度量。 该评分基于我国上市公司的社会责任报告和财务报告信息,从股东责任、员工责任、供应商、客户和消费者权益责任、环境责任和公共责任五个方面,分别设立13个二级指标和37个三级指标,对企业社会责任承担情......
  • 反悔贪心
    1.介绍贪心:即考虑局部最优解达到全局最优解的目的,但有时局部最优解并不会达到全局最优解,此时有两种思考方向,dp和反悔贪心dp:能全局计算答案,根据拓扑学的DAG实现状态转移达到最优(这里不过多介绍)反悔贪心:根据之前的决策进行反悔操作,主要用反悔堆实现去除性价比最低的决策,达到......
  • 反悔贪心学习笔记
    本文仅用于笔者关于反悔贪心的学习笔记,反悔贪心是笔者在一场$div4$中遇到的问题,故来学习一番【学习笔记】反悔贪心 1、什么是反悔贪心?贪心本身是没有反悔操作的,贪心求的就是当前的最优解。但当前的最优解有可能是局部最优解,而不是全局最优解,这时候就要进行反悔操......
  • 挑战程序设计竞赛 2.2章习题 POJ - 3617 Best Cow Line 贪心
    FJ正准备带着他的N头奶牛(1≤N≤2,000)参加一年一度的“年度最佳农民”比赛。在这个比赛中,每个农民都会将他的奶牛排成一行,然后引导它们经过评委。今年比赛的组织者采用了一种新的注册方案:只需按照它们出现的顺序注册每头奶牛的首字母(即如果FJ带着Bessie、Sylvia和Dora依次出......
  • 各省高校在广东2023/2022/2021录取分数线下载
    为了帮助考生更好地进行志愿填报,更好的对数据筛选,故整理各省高校在广东2023/2022/2021三年录取分数excel文件,部分数据及文件见下图,数据根据历年录取分数线汇总,仅供参考,详细请登陆各高校网站查询。如有需要,可根据步骤下载文件:文件列表及数据如下图所示,数据实测真实有效。关......