算法-贪心算法 学习理解
在算法中,有一种算法叫做 贪心算法(Greedy Algorithm). 贪心算法的特点是 在每一步都选择当前"最优" (局部最优)的解, 希望能够借此得到全局的最优解. 它有以下特点
1. 贪心选择(Greedy Choice) : 每一步都能做出局部最优的选择
2. 无后效性(No Aftereffect) 当前选择不会影响后续的选择
3. 最优子结构: 局部最优解能够构造全局最优解
注意:贪心算法指在对问题进行求解时,在每一步的选择中都采取最好或者最优(即最有利)的选择,从而希望最终结果也是最好或者最优的选择. 但是,贪心算法所得到的结果不一定就是最优的结果,有时候确实是最优解,但有时候可能就是相对近似或接近最优解的结果
我们来看看经典的贪心算法题目
题目1: 背包放物品问题
给定一组物品和背包容量,要求选择物品放入背包,使得总价值最大,且不超过背包容量
public class Item
{
public string Name {get; set;}
public int Weight {get; set;}
public int ItemValue {get; set;}
public double ValuePerWeight => (double)ItemValue / Weight;
}
public class Bag
{
private int weightCapacity;
public Bag(int _capacity)
{
weightCapacity = _capacity;
}
public IList<Item> MaxValueItemsToBag(IList<Item> items)
{
var sortedItems = items.OrderByDescending(i => i.ValuePerWeight).ToList();
var result = new List<Item>();
var sumWeight = 0;
foreach(var currItem in sortedItems)
{
//sortedItem已经按照valuePerWeight从大到小排序,所以循环的每一步都是当时的最优解
if(sumWeight + currItem.Weight <= weightCapacity)
{
sumWeight += currItem.Weight;
result.Add(currItem);
}
}
}
}
题目2 商店找零问题,假设商店要找零amount元,硬币的面值有 {1,5,10,25,50}美分
题目要求: 用最少数量的硬币找零
贪心算法解题策略: 每次都选择当前最大面值的硬币,直到总额满足amount
using System;
using System.Collections.Generic;
class GreedyChange
{
public static void Main()
{
int amount = 87; // 需要找零 87 美分
int[] coins = { 50, 25, 10, 5, 1 }; // 硬币面值(已按降序排列)
List<int> result = GetChange(amount, coins);
Console.WriteLine($"找零 {amount} 美分的最少硬币组合:");
foreach (var coin in result)
{
Console.Write(coin + " ");
}
}
static List<int> GetChange(int amount, int[] coins)
{
List<int> result = new List<int>();
foreach (var coin in coins)
{
while (amount >= coin) // 选择当前面值最大的硬币
{
amount -= coin;
result.Add(coin);
}
}
return result;
}
}
浙公网安备 33010602011771号