背包分组问题的解法讨论
还是喜欢看算法题。。因为算法很菜。。哈哈。
题目请参见: eaglet 背包分组问题的解法
也花了近两个小时吧, 凭着直觉做了一下, 大家给点意见. 直接贴代码了, 感觉还是比较清晰的, 一看就懂。好吧好吧,这么多人问。。加算法说明在最后。
1: using System;
2: using System.Collections.Generic;
3:
4: namespace BagQuest
5: {
6: class Program
7: {
8: /// <summary>
9: /// main function
10: /// </summary>
11: /// <param name="args">arguments</param>
12: static void Main(string[] args)
13: {
14: int[] goods = { 25, 15, 10, 3, 1, 5, 14, 16, 5, 6 };
15: int[] sizes = { 35, 45, 20 };
16: var usedIndex = new int[goods.Length];
17:
18: var result = new List<int>[sizes.Length];
19:
20: var sortedGoods = SortFromBigToSmall(goods);
21: var sortedSizes = SortFromBigToSmall(sizes);
22: for (var sIndex = 0; sIndex < sortedSizes.Length - 1; sIndex++)
23: {
24: var addHelper = 0;
25: for (var i = 0; i < sortedGoods.Length; i++)
26: {
27: if (usedIndex[i] != 1 && usedIndex[i] != 2 && sortedGoods[i] + addHelper <= sortedSizes[sIndex])
28: {
29: usedIndex[i] = 1; // mark the index as used
30: addHelper += sortedGoods[i];
31: }
32:
33: if (addHelper == sortedSizes[sIndex] || i == sortedGoods.Length - 1)
34: {
35: result[sIndex] = MemoryTheResult(sIndex, ref usedIndex, goods);
36: addHelper = 0;
37: break;
38: }
39: }
40: }
41:
42: var maxResultIndex = result.Length - 1;
43: result[maxResultIndex] = new List<int>();
44: for (var i = 0; i < usedIndex.Length; i++)
45: {
46: if (usedIndex[i] != 1 && usedIndex[i] != 2)
47: {
48: result[maxResultIndex].Add(sortedGoods[i]);
49: }
50: }
51:
52: #region OUTPUT
53:
54: for (var sIndex = 0; sIndex < sortedSizes.Length; sIndex++)
55: {
56: Console.Write("\n{0} : ", sortedSizes[sIndex]);
57: for (int rIndex = 0; rIndex < result[sIndex].Count; rIndex++)
58: {
59: Console.Write("{0} ", result[sIndex][rIndex]);
60: }
61: }
62: Console.WriteLine();
63: #endregion
64: }
65:
66: /// <summary>
67: /// record the result to result array
68: /// </summary>
69: /// <param name="sIndex">the index of the result</param>
70: /// <param name="usedIndex">draft result record</param>
71: /// <param name="goods">the item source</param>
72: /// <returns>a final result record</returns>
73: private static List<int> MemoryTheResult(int sIndex, ref int[] usedIndex, int[] goods)
74: {
75: var resultList = new List<int>();
76: for (var i = 0; i < usedIndex.Length; i++)
77: {
78: if (usedIndex[i] == 1)
79: {
80: resultList.Add(goods[i]);
81: usedIndex[i] = 2;
82: }
83: }
84: return resultList;
85: }
86:
87: /// <summary>
88: /// sort the array
89: /// </summary>
90: /// <param name="goods">item source</param>
91: /// <returns>the sorted (big to small) item array </returns>
92: private static int[] SortFromBigToSmall(int[] goods)
93: {
94: for (int j = 0; j < goods.Length; j++)
95: {
96: for (int i = 0; i < goods.Length; i++)
97: {
98: if (goods[j] > goods[i])
99: {
100: var temp = goods[j];
101: goods[j] = goods[i];
102: goods[i] = temp;
103: }
104: }
105: }
106:
107: return goods;
108: }
109: }
110: }
大家感觉如何? 多拍砖哈。。。
算法说明:
先把“原料”按照从大到小排序,再把“包”从大到小排序
然后把原料从最大的开始累加,如果超过了包的大小,就跳过,累加下一个(下一个会更小),如果超过,就再跳过。。如此找到最接近的组合。
只需找两组,剩下的就是第三组。
大致如此。