动态规划之背包问题原理详细推导及其实现

贪心算法:

(1)      给定n个物品,物品价值分别为P1P2,…,Pn,物品重量分别W1W2, …, Wn,背包容量为M。每种物品可部分装入到背包中。输出X1X2,…,Xn,0<Xi<1, 使得 最大,且 <M。试设计一个算法求解该问题,分析算法的正确性.

解:

  设计思路:首先将n个物品按单位价值从大到小排序,每次取剩余物品中单位价值最大的物品放入背包,若背包的容量足够则放入整个物品,否则放入物品的一部分。

  最优子结构性质


贪心选择性:


综上所述,该算法具有贪心选择性。

算法的源代码如下:

// Test.cpp : 定义控制台应用程序的入口点。
#include "stdafx.h"
#include <iostream>
#include <algorithm>
#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 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;
    int bagvol;
    double total_value=0;
    double total_weight=0;
	Goods *G;
    cout<<"请输入背包的容量:"<<endl;
    cin>>bagvol;
    cout<<"请输入商品的种类:"<<endl;
    cin>>goods_num;
   // Goods G[goods_num+1];
	G= new Goods[goods_num+1];
    cout<<"请输入商品的重量和价值:"<<endl;
    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
    }

    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<<"背包容量为: "<<bagvol<<endl;//输出背包容量
    cout<<"装入物品的总重量为: "<<total_weight<<endl;//输出装入物品的总重量
    cout<<"装入物品的最大价值为: "<<total_value<<endl;//输出装入物品的总价值
	return 0;

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值