贪心法是求解一类最优化问题的方法,它总是考虑在当前状态下局部最优(或较优)的策略,来使全局的结果达到最优(或较优)。显然,如果采用较优而非最优的策略,得到的全局结果也无法是最优的。而要获得最优结果,则要求中间的每步策略都是最优的,因此严谨使用贪心法来求解最优化问题需要对采取的策略进行证明。不过对于平常使用来说,也许没有时间或不太容易对想到的策略进行严谨的证明,因此一般来说,如果在想到某个似乎可行的策略,并且自己无法举出反例,那么就勇敢的实现它
简单贪心
题目:
贪心法思路:
猜想:采用“总是选择单价最高的月饼出售,可以获得最大的利润”。
证明:假设有两种单价不同的月饼,其单价分别为a和b。如果当前需求量为K,那么两种月饼的总收入分别为aK和bK,而aK<bK显然成立,因此需要出售单价更高的月饼
实现代码
typedef struct
{
double store;
double sell;
double price;
}CakeOne,Cake[100];
bool cmp(CakeOne a, CakeOne b)
{
return a.price > b.price;
}
double CountMoney(Cake cake,int need,const int& num)
{
double maxmoney = 0;
sort(cake, cake + num, cmp);
for (int i = 0; i < num; ++i)
{
//能全部卖完
if (cake[i].store <= need)
{
maxmoney += cake[i].sell;
need -= cake[i].store;
}
else
{
maxmoney += cake[i].price * need;
break;
}
}
return maxmoney;
}
int main()
{
Cake cake;
int num,need;
cin >> num >> need;
for (int i = 0; i < num; ++i)
{
cin >> cake[i].store;
}
for (int i = 0; i < num; ++i)
{
cin >> cake[i].sell;
cake[i].price = cake[i].sell / cake[i].store;
}
double maxmoney = CountMoney(cake,need,num);
printf("%.2lf", maxmoney);
return 0;
}
区间贪心
区间不相交问题:给出N个开区间(x,y),从中选择尽可能多的开区间,使得这些开区间两两没有交集。
贪心思路:
代码实现:
typedef struct
{
int x;
int y;
}Interval, IntervalArray[100];
bool cmp(Interval a, Interval b)
{
if (a.x != b.x)
return a.x > b.x;
else
return a.y < b.y;
}
int main()
{
int num;
cin >> num;
IntervalArray ia;
for (int i = 0; i < num; ++i)
cin >> ia[i].x >> ia[i].y;
sort(ia, ia + num,cmp);
int cur = INT_MAX;
for (int i = 0; i < num; ++i)
{
if (ia[i].y <= cur)
{
cout << "(" << ia[i].x << "," << ia[i].y << ")" << endl;
cur = ia[i].x;
}
}
return 0;
}