【贪心算法】背包问题
来源:互联网 发布:网络电视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
- 贪心算法 - 背包问题
- 贪心算法----背包问题
- 【贪心算法】:背包问题
- 贪心算法-背包问题
- 贪心算法 背包问题
- 贪心算法-背包问题
- 【贪心算法】背包问题
- 贪心算法-背包问题
- 贪心算法--背包问题
- 背包问题-贪心算法
- 背包问题的贪心算法
- 背包问题(贪心算法)
- acm-背包问题(贪心算法)
- 背包问题(贪心算法)
- 贪心算法解决背包问题
- 分数背包问题(贪心算法)
- nyoj106背包问题【贪心算法】~
- 背包问题的贪心算法
- libpcap详解
- A Typical Homework(UVa 12412)
- POJ 1260 Pearls DP
- 风一直吹,我一直跑——小记2016年终总结
- 二叉树非递归三种遍历
- 【贪心算法】背包问题
- 【Leetcode】205. Isomorphic Strings
- 算法
- Python:数据文件的打开模式和操作方法
- 【Java语言程序设计(基础篇)第10版 练习题答案】Practice_9_4
- 11.3.5
- c指针应用:键值对"key=value"字符串,在开发中经常使用
- 算法训练 5-1最小公倍数
- win10,ubuntu双系统和win10,红帽双系统的安装的异同