贪心算法
贪心策略
贪心算法是指在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,它所做出的仅是在某种意义上的局部最优解。用局部解构造全局解,即从问题的某一个初始解逐步逼近给定的目标,以尽可能快的求得更好的解。当某个算法中的某一步不能再继续前进时,算法停止。
贪心策略:将问题分成多个子问题;子问题求局部最优解;局部最优解组合成原问题的解。
Kruskal,Prim算法
分类:简单贪心 区间贪心
咖啡豆问题
题目描述
FatMouse prepared M pounds of cat food, ready to trade with the cats guarding the warehouse containing his favorite food, JavaBean.
The warehouse has N rooms. The i-th room contains J[i] pounds of JavaBeans and requires F[i] pounds of cat food. FatMouse does not have to trade for all the JavaBeans in the room, instead, he may get J[i]* a% pounds of JavaBeans if he pays F[i]* a% pounds of cat food. Here a is a real number. Now he is assigning this homework to you: tell him the maximum amount of JavaBeans he can obtain.
输入
The input consists of multiple test cases. Each test case begins with a line containing two non-negative integers M and N. Then N lines follow, each contains two non-negative integers J[i] and F[i] respectively. The last test case is followed by two -1’s. All integers are not greater than 1000.
输出
For each test case, print in a single line a real number accurate up to 3 decimal places, which is the maximum amount of JavaBeans that FatMouse can obtain.
样例输入
4 2
4 7
1 3
5 5
4 8
3 8
1 2
2 5
2 4
-1 -1
1
2
3
4
5
6
7
8
9
10
样例输出
2.286
2.500
#include <cstdio> #include <iostream> #include <algorithm> using namespace std; const int MAXN = 1000; struct JavaBean{ double J; //咖啡豆 double F; //支付 double unitPrice; //运算符重载 bool operator<(JavaBean bean) const{ if(unitPrice == bean.unitPrice){ return F > bean.F; }else{ return unitPrice < bean.unitPrice; } } }; JavaBean arr[MAXN]; int main(){ int m,n; while(scanf("%d%d",&m,&n) != EOF){ double res = 0.00; if(m == -1 && n == -1){ break; } //输入 for(int i = 0;i < n;i++){ scanf("%lf%lf",&arr[i].J,&arr[i].F); } //计算单价 for(int i = 0;i < n;i++){ arr[i].unitPrice = arr[i].F / arr[i].J; } sort(arr,arr+n); //贪心策略,输出 for(int i = 0;i < n;i++){ if(m <= 0){ break; }else if(m > arr[i].F){ res += arr[i].J; m -= arr[i].F; }else{ int rate = m/arr[i].F; res += arr[i].J * rate; m -= arr[i].F * rate; } } printf("%.3f\n",res); } return 0; }
背包问题
有一组 1 维的物品需要打包进一批同样的箱子中。所有的箱子有完全一样的长度 l 以及每一个物品长度 li<=l. 我们要找到一个最小的数字 q, 使得 :
(1) 每个箱子最多包含两个物品
(2) 每个物品要被包含在 q 个箱子中的一个中
(3) 在箱子中物品的总长度不能超过 l
你的任务是,给定 n 个整数,l,l1,l2….ln, 计算最小的箱子总数 q.
输入格式
第一行包含一个数字 n(1<= n <= 10^5), 表示有几个物品。第二行包含一个整数表示了箱子的长度 l (l<=10000). 接下去的 n 行是表示了每个物品的长度。
输出格式
输出一个整数,表示能够包含所有物品的最小的箱子总数。
提示 :
The sample instance and an optimal solution is shown in the figure below. Items are numbered from 1 to 10 according to the input order.
思考:如果每次选择两个最大的,可能一次性溢出;如果每次挑选两个最小的,可能后面又会溢出,选择的是最大的和最小的,如果首次他们都未通过