算法——动态规划
2012-12-26 19:33 msfte 阅读(181) 评论(0) 编辑 收藏 举报1,编程之美1.4买书问题
上柜的《哈利波特》平装本系列,一共有五卷。假设每一卷单独销售均需8欧元。如果读者一次购买不同的两卷,就可以扣除5%的费用,三卷则更多。假设具体折扣的情况如下:
本数 2 折扣 5%
本数 3 折扣 10%
本数 4 折扣 20%
本数 5 折扣 25%
问题:设计出算法,能够计算出读者所购买的一批书的最低价格。
备忘录算法:
class BuyBook { public void Run() { var result = DynamicProgramming(new int[] { 2,2,2,1,1}); } double DynamicProgramming(int[] books) { books = books.OrderByDescending(c => c).ToArray(); return DynamicProgrammingRecur(books); } double DynamicProgrammingRecur(int[] books) { if (books[0] == 0) return 0; if (cache.ContainsKey(new BookState(books))) return cache[new BookState(books)]; books = books.OrderByDescending(c => c).ToArray(); double situation1 = 8 + DynamicProgrammingRecur(new int[] { books[0] - 1, books[1], books[2], books[3], books[4] }); double situation2 = books[1] != 0 ? 8 * 2 * (1 - 0.05) + DynamicProgrammingRecur(new int[] { books[0] - 1, books[1] - 1, books[2], books[3], books[4] }) : 0; double situation3 = books[2] != 0 ? 8 * 3 * (1 - 0.1) + DynamicProgrammingRecur(new int[] { books[0] - 1, books[1] - 1, books[2] - 1, books[3], books[4] }) : 0; double situation4 = books[3] != 0 ? 8 * 4 * (1 - 0.2) + DynamicProgrammingRecur(new int[] { books[0] - 1, books[1] - 1, books[2] - 1, books[3] - 1, books[4] }) : 0; double situation5 = books[4] != 0 ? 8 * 5 * (1 - 0.25) + DynamicProgrammingRecur(new int[] { books[0] - 1, books[1] - 1, books[2] - 1, books[3] - 1, books[4] - 1 }) : 0; double max = GetMax(new double[] { situation1, situation2, situation3, situation4, situation5 }); cache.Add(new BookState(books), max); return max; } double GetMax(double[] items) { double max = items[0]; for (int i = 1; i < items.Length; i++) if (items[i] > max) max = items[i]; return max; } Dictionary<BookState, double> cache = new Dictionary<BookState, double>(); } struct BookState { public BookState(int[] state) { this.State = state; } public int[] State; public override bool Equals(object obj) { int[] objState = obj as int[]; if (objState == null) return false; else { for (int i = 0; i < State.Length; i++) if (State[i] != objState[i]) return false; return true; } } public override int GetHashCode() { int hashCode = 0; for (int i = 0; i < State.Length; i++) { int currentNumber = State[i]; for (int j = 0; j <= i; j++) currentNumber *= 10; hashCode += currentNumber; } return hashCode; } }