算法实验项目 -背包问题

给定个物品和一个容量为的背包,物品i的重量是,其价值为。背包问题是如何选择装入背包的物品,使得装入背包中的物品总价值最大?(物品可以分割)

Input

单组数据输入。
第一行:两个整数和。表示物品的个数和背包的容量。
下面有行,每行有两个整数和,分别表示每个物品的重量和价值。

Output

第一行:一个浮点数,表示能装入背包的最大价值。保留小数点后两位
第二行:个整数,表示个物品装入背包的重量。并以空格隔开。(按输入顺序排列,即第一个数为物品1装入背包的重量)

Sample input

3 50
20 60
30 120
10 50

Sample output

200.00
10 30 10

#include <iostream>  
#include <algorithm>  
#include<iomanip>
#include<stdio.h>
#define MAX_NUM 1000  
using namespace std;  
struct Goods //info of goods定义物品信息结构体  
{  
    int weight;// the weight of goods重量  
    int value;// the value of goods价值  
    double ValPerWei;// value per weight权重  
    double load; //物品装入背包的部分的系数(物品全部装入则load为1,装入10/20则load为0.5)  
    int id;
};  
int cmp( Goods const &a, Goods const &b)//定义sort函数的比较函数  
{  
    if(a.ValPerWei<b.ValPerWei) return 0;  
    else return 1;  
}  
void Greedy(Goods g[],int good_num, int content)//贪心算法  
{  
    for(int i=0; i<good_num; i++)  
    {  
        if(content>g[i].weight)//如果背包足够装下整个物品  
        {  
            content-=g[i].weight;  
            g[i].load=1;  
        }  
        else if(content>0){//如果背包不足以装下整个物品  
            g[i].load=(double)content/g[i].weight;//计算物品装入背包的部分  
            content=0;//背包容量置0  
            return;//程序结束,返回  
        }  
    }  
}  
int main()  
{  
    int goods_num;  
    double bagvol;  
    double total_value=0;  
    double total_weight=0;  
    int ib=0;
    cin>>goods_num>>bagvol;   
    Goods G[goods_num+1];
    for(int i=0; i<goods_num; i++)  
    {  
        cin>>G[i].weight>>G[i].value;//输入重量价值  
        G[i].ValPerWei=(double)G[i].value/G[i].weight;//计算权重  
        G[i].load=0;//load置0  
        G[i].id=ib;
        ib++;
    }  

    sort (G,G+goods_num,cmp);//sort by ValPerWei  

    Greedy(G,goods_num,bagvol);  
    for(int i=0;i<goods_num;i++)//output the info of goods  
    {  
        if(G[i].load==0.0)break;//如果检测到物品未被装入背包,则推出循环  

        total_value+=(G[i].value*G[i].load);//装入背包的物品总价值  
        total_weight+=(G[i].weight*G[i].load);//装入背包的物品总重量  
        //cout<<"weight: "<<G[i].weight<<"  "<<"value: "<<G[i].value<<"  "<<"the value per weight of good: "<<G[i].ValPerWei<<"  the part of goods: "<<G[i].load<<endl;//输出装入背包的物品信息  
    }   
    printf("%.2lf",total_value);//输出装入物品的总价值 
    cout<<endl; 
    int j=0,i=0;
    for( j=0;j<goods_num;j++)
    {
        for(i=0;i<goods_num;i++)
        {
        if(G[i].id==j&&j!=goods_num-1)
        cout<<G[i].load*G[i].weight<<" ";
        else if(G[i].id==j&&j==goods_num-1)
        cout<<G[i].load*G[i].weight<<endl;
        }
    }
}  

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值