【贪心算法】背包问题

来源:互联网 发布:网络电视32寸多少钱 编辑:程序博客网 时间:2024/04/29 18:16

在之前的《算法设计与分析》课程的学习中,我们就接触到了贪心算法解决背包问题,当然还有动态规划法解决0-1背包问题等等。今天我就来分析贪心法解决背包问题。为了大家可以理解贪心算法,我先分享一道比较简单的题目。


问题描述:

给你一个非负数整数n,判断n是不是一些数(这些数不允许重复使用,且为正数)的阶乘之和,如9=1!+2!+3!,如果是,则输出Yes,否则输出No;
第一行有一个整数0

问题分析:

看到这个问题,我并不是一下子就想到了解决办法,只是参考一些资料。列出前9个数字的阶乘。存储在一个数组中,为什么是前9个数呢?因为n<1000000,而9的阶乘就是362880,10!一定大于1000000.具体实现办法:每次都从9的阶乘开始(也就是数组的最后一个数字),如果给出的n大于数组的当前数字,则n减去当前数字;如果n小于当前数字,则遍历数组前边的数字,直到n为0或者是已经到达数组的开始就退出循环.


代码实现:

#include<iostream>using namespace std;bool IsSum(int num){       if (num <= 0)              return false;       int  factorialArr[] = { 1,2,6,24,120,720,5040,40320,362880 };       int index = 8;       while (num > 0 && index >= 0)       {              if (num - factorialArr[index] >= 0)                     num -= factorialArr[index];              index--;//由于数据不能重复,所以无论减的结果是否大于0,index都要前移       }       if (num == 0)              return true;       else              return false;}int main(){       int n = 0;       cin >> n;       while (n--)       {              int num = 0;              cin >> num;              if (IsSum(num))              {                     cout << "Yes" << endl;              }              else                     cout << "No" << endl;       }       system("pause");       return 0;}

从上边的题目,我们大致就可以知道贪心的思想–今朝有酒今朝醉。下边我们来分析背包问题。

背包问题:给出背包所能装载的最大重量,给出需要装进去的物品的重量和价值。每次需要装入的是单位重量价值最高的物品。由于容量问题,如果不能装入某一件物品,我们可以根据背包的剩余容量和物品的重量,决定装入物品的多少。背包问题与0-1背包的不同之处就是:0-1背包就是装就要完全装入,不能完全装入就不要装;背包问题可以装入物品的部分。

代码实现:

#include<iostream>using namespace std;#include<cassert>#include<algorithm>//背包问题struct Object{       int _num;//物品的序号       int _weight;       int _value;       float _valuePerWeight;//每重量的价值};bool Compare(const Object& l, const Object& r){       return l._valuePerWeight > r._valuePerWeight;}void Knapsack(Object objects[], int n,int capacity){       assert(objects && n && capacity);       int index = 0;       int value = 0;       //贪心算法实现       while (index < n)       {              if (objects[index]._weight <= capacity)              {                     printf("可以完全装进去第%d件物品\n", objects[index]._num);                     capacity -= objects[index]._weight;                     value += objects[index]._value;                     ++index;              }                    else//装不下一整件物品的情况              {                     float proportion = (float)capacity / objects[index]._weight;                     printf("只能装进第%d件物品的%f\n", objects[index]._num, proportion);                     value += (proportion*objects[index]._value);                     break;              }       }       printf("背包所能装物品的价值总和为:%d\n", value);}int main(){       int capacity = 0;//背包所能承受的容量       cout << "背包所能承受的容量>:";       cin >> capacity;       int nObjects = 0;       cout << "需要装入包的物品数>:";       cin >> nObjects;//需要装入包的物品数       Object* objects = new Object[nObjects];       cout << "依次输入每个物品的重量和价值"<<endl;       for (int i = 0; i < nObjects; ++i)       {              objects[i]._num = i + 1;              cin >> objects[i]._weight >> objects[i]._value;              objects[i]._valuePerWeight = (float)(objects[i]._value) / (objects[i]._weight);       }       sort(objects, objects + nObjects, Compare);       Knapsack(objects, nObjects,capacity);       delete[] objects;       system("pause");       return 0;}

运行结果
这里写图片描述

0 0
原创粉丝点击