实施分数背包

Posted

技术标签:

【中文标题】实施分数背包【英文标题】:Implement Fractional knapsack 【发布时间】:2016-09-30 18:32:10 【问题描述】:

我试图通过首先按对象的值与对象的重量之比对元素进行排序来实现分数背包。我正在使用对的向量,其中对的第一个元素是对象的值,对的第二个元素是权重。 compbyrat 函数用于通过值与权重的比率来比较向量元素。我收到以下代码的运行时错误。谁能帮我找出错误?

#include <iostream>
#include<algorithm>
#include<vector>
#include<utility>
using namespace std;
bool compbyrat(const pair<long long int,long long int> &a, const pair<long long int,long long int> &b)

    return ((double)a.first/(double)a.second)< ((double) b.first/(double) b.second) ;

int main() 
    long long int n, weight;
    vector<pair<long long int,long long int> > v;
    cin>>n>>weight;
    for(long long int i = 0; i < n; i++)
        cin>>v[i].first>>v[i].second;
    

    sort(v.begin(), v.end(), compbyrat);
    long long int currentweight = 0, ans =0;
    for(long long int i =0; i < n && currentweight < weight; i++)
        if(currentweight + v[i].second <= weight)
            ans = ans + v[i].first;
        
        else
            ans = ans + (((double)v[i].first/(double)v[i].second) * (weight -currentweight));
        
    
    cout<<ans;
    return 0;

【问题讨论】:

一开始,你还没有初始化你的向量。在你读过 n 和 weight 之后添加一个 "v.resize(n)" 行。访问空向量的元素是一个 UB。 调试器是解决此类问题的正确工具。 询问 Stack Overflow 之前,您应该逐行浏览您的代码。如需更多帮助,请阅读How to debug small programs (by Eric Lippert)。至少,您应该 [编辑] 您的问题以包含一个重现您的问题的 Minimal, Complete, and Verifiable 示例,以及您在调试器中所做的观察。 谢谢。知道了。时隔 2 年开始用 C++ 编码,忘记了很多东西。 【参考方案1】:

我能够通过一些修改来解决它。代码如下,

#include <iostream>
#include<algorithm>
#include<vector>
#include<utility>
#include<iomanip>
using namespace std;
bool compbyrat(const pair<long long int,long long int> &a, const pair<long long int,long long int> &b)

    return ((double)((double)a.first/(double)a.second)> (double)((double) b.first/(double) b.second)) ;

int main() 
    long long int n, weight;
    cin>>n>>weight;

    vector<pair<long long int,long long int> > v(n+2);
    for(long long int i = 0; i < n; i++)
        cin>>v[i].first>>v[i].second;
    

    sort(v.begin(), v.end(), compbyrat);
    //cout<<v[0].first;
    long long int currentweight = 0;
    double ans = 0.0000;
    for(long long int i =0; i < n && currentweight < weight; i++)
        if(currentweight + v[i].second <= weight)
            ans = ans + v[i].first;
            currentweight = currentweight + v[i].second;
            //cout<<v[i].first<<" "<<v[i].second<<endl;
        
        else
            ans = ans + ((double)((double)v[i].first/(double)v[i].second) * (weight -currentweight));
            currentweight = currentweight + v[i].second;
        


    
    cout<<fixed << setprecision(4)<<ans;
    return 0;

【讨论】:

以上是关于实施分数背包的主要内容,如果未能解决你的问题,请参考以下文章

C#分数背包o(n logn)解

51nod 1257 背包问题 V3(分数规划)

python 贪心算法解决分数背包问题

请帮助我解决分数背包问题(战利品的最大值)

bzoj4753: [Jsoi2016]最佳团体(分数规划+树形依赖背包)

P4322 [JSOI2016]最佳团体(分数规划&树上背包)