已知总金额和几个商品单价,查找每个商品各取几个可以最接近或等于总价,取最优解实现程序
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Xml.Serialization; namespace ConsoleApp1 { class Program { static void Main(string[] args) { //10个试剂 var materialList = new List<Material>(); for (int i = 0; i < 5; i++) { var material = new Material() { Code = i + 1, Name = "Material" + (i + 1).ToString(), Price = (i + 1), }; materialList.Add(material); material.QtyList = new List<int>(); int j = 1; //最多取20个 while (j <= 5) { material.QtyList.Add(j); j++; } } Console.WriteLine($"MaterialList = {Newtonsoft.Json.JsonConvert.SerializeObject(materialList)}"); decimal total = 0; int totalAmount = 70; bool flag = false; var diffList = new List<Diff>(); plus(new Diff(), materialList, diffList, totalAmount, total, ref flag); var diff = diffList.OrderBy(p => p.DiffAmt).FirstOrDefault(); Console.ReadLine(); } public static void plus(Diff diff, List<Material> materialList, List<Diff> diffList, decimal totalAmount, decimal total, ref bool flag) { if (flag) return; if (materialList != null && materialList.Any()) { var material = materialList.First(); var list = materialList.Where(p => p.Code != material.Code).ToList(); foreach (var qty in material.QtyList) { if (flag) break; if (totalAmount >= material.Price * qty + total) { var oldTotal = total; oldTotal += material.Price * qty; UpdateDiff(diff, material.Code, qty); if (list.Any()) plus(diff, list, diffList, totalAmount, oldTotal, ref flag); else { diff.DiffAmt = totalAmount - oldTotal; diffList.Add(DeepCopy(diff)); Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(diff)); if (diff.DiffAmt == 0) { flag = true; break; } } } } } } /// <summary> /// 深度拷贝对象 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="obj"></param> /// <returns></returns> public static T DeepCopy<T>(T obj) { object retval; using (MemoryStream ms = new MemoryStream()) { XmlSerializer xml = new XmlSerializer(typeof(T)); xml.Serialize(ms, obj); ms.Seek(0, SeekOrigin.Begin); retval = xml.Deserialize(ms); ms.Close(); } return (T)retval; } public static void UpdateDiff(Diff diff, int index, int qty) { var propName = "Number" + index.ToString(); if (diff.GetType().GetProperty(propName) != null) { diff.GetType().GetProperty(propName).SetValue(diff, qty); } } public static void showLog(List<int> list) { string str = string.Join(",", list.ToArray()); Console.WriteLine(str); } } public class Material { public int Code { get; set; } public string Name { get; set; } public decimal Price { get; set; } public int Qty { get; set; } public List<int> QtyList { get; set; } } public class Diff { public int Number1 { get; set; } public int Number2 { get; set; } public int Number3 { get; set; } public int Number4 { get; set; } public int Number5 { get; set; } public int Number6 { get; set; } public int Number7 { get; set; } public int Number8 { get; set; } public int Number9 { get; set; } public int Number10 { get; set; } public decimal DiffAmt { get; set; } } }