从小李就有个坏毛病,就是喜欢贪心。一天,他在街上捡到一颗闪闪发光的宝石。他想,我可以卖了这颗宝石,就能变成百万富翁了!于是他兴高采烈地找上了一位宝石商人。商人看了看宝石,笑了笑说:“这颗宝石可是有着神奇的力量,能让人实现一个愿望。”李一听,心中冒起了无数的欲望,立刻决定要自己使用这颗宝石。然而,当李捧着宝石许愿时,宝石突然碎裂成了两半。李惊愕的看着两半的宝石,愚蠢的贪心使他失去了更多。
好啦! 今天的主角叫“贪心”, 贪心是局部最优的解 ,它是不从整体最优来考虑 , 贪心使用一个整体的问题可以用局部的最优解推导得到全局的解 , 但是 , 对于某些问题, 虽然局部是最优的解 , 但是考虑全局 , 却不是最优的解!
尽管这样 , 但是贪心算法任然不失为一种非常实用的算法 。 今天带来一道简单的经典的贪心问题 (太难的我也不会哈哈) —— 洛谷P2240 <<部分背包问题>>。
题目描述
题目我口述吧(言简意赅哦) , 一个人要拿金币 , 金币是成堆的 , 每一堆都相应的体积,相应的价值,这个人背一个包 ,包有一定的体积 , 现在要在有限的背包体积中, 装的金币钱最多 。问:最多价值是多少 ?(注意: 金币堆是可以分割的哦)
代码描述(就知道前面是废话)
#include<bits/stdc++.h>
using namespace std;
const int N = 105;
//结构体更方便
struct node
{
double w;//重量
double v;//体积
double p;//单个性价比
}a[N];
int n ;
double sum , m;
bool cmp(node x , node y)
{
return x.p > y.p;//排序性价比
}
int main()
{
cin>>n>>m;
for(int i = 1 ; i<= n ; i++)
{
cin>>a[i].w>>a[i].v;
a[i].p =(double) a[i].v / a[i].w;//计算单个性价比
}
sort(a +1, a + n +1, cmp);//排序
for(int i = 1 ; i <= n ; i++)
{
if(m >= a[i].w)//先把能拿的拿够
{
sum += a[i].v;
m -= a[i].w;//减去所拿物品的体积
}
else//背包剩多少拿多少
{
sum += m*a[i].p;//m所剩的体积乘以性价比哦!
break;
}
}
printf("%.2lf",sum);
return 0;
}
总结
贪心就是这个思想 ,了解了思想, 快去刷题吧!