贪心算法并不能让问题的每一个情况都实现最优解
活动选择问题
使用穷举法
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ActionSelect { class Program { public static int[ ,] list=new int[11,11];//存储每一种情况时,一天的具体有哪些活动 static void Main(string[] args) { int[] s = new int[] { 1,3,0,5,3,5,6,8,8,2,12};//活动开始时间 int[] f = new int[] {4,5,6,7,8,9,10,11,12,13,14 };//活动结束时间 MaxAction(s,f);//算出每一个情况的具体有哪些活动 for (int i = 0; i < list.GetLength(0); i++)//输出在24小时内每一种情况时,举办的具体活动 { for (int j = 0; j <list.GetLength(1); j++)//Array.GetLength(0)获取二维数组的纵坐标个数 { if (list[i, j] != 0) { Console.Write(list[i, j]);//输出一天举办的具体活动 } } Console.WriteLine();//换行 } Console.ReadKey(); } /// <summary> /// 获取一天举办最多活动的情况 /// </summary> /// <param name="s"></param> /// <param name="f"></param> private static void MaxAction(int[] s, int[] f) { for (int i = 0; i < s.Length; i++) { int temp = f[i]; list[i, 0] = i+1; for (int j = 1; j < f.Length; j++) { if(temp<=s[j]) { temp = f[j]; list[i, j] = j+1; } } } } } }
使用贪心算法解决活动选择问题
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Greed { class Program { static void Main(string[] args) { int[] s = new int[] { 0,1, 3, 0, 5, 3, 5, 6, 8, 8, 2, 12 };//活动开始时间 int[] f = new int[] { 0,4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 };//活动结束时间 int StartTime = 0;//活动开始时间 int EndTime = 24;//活动结束时间 List<int> list = new List<int>();//存储活动 for (int i = 1; i <= s.Length-1; i++)//从第一个活动遍历到最后一个活动 { if(s[i]>=StartTime&&f[i]<=EndTime)//在设置的时间段内查找在这个时间段的活动 { StartTime = f[i];//查找到之后修改时间段 list.Add(i);//将查找到的时间段存储起来 } } foreach (var item in list)//将时间段全部打印出来 { Console.WriteLine(item); } Console.ReadKey(); } } }
使用动态算法实现活动选择问题
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ActionSelect1 { class Program { static void Main(string[] args) { int[] s = new int[] { 0,1, 3, 0, 5, 3, 5, 6, 8, 8, 2, 12,24 };//活动开始时间 int[] f = new int[] { 0,4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,24 };//活动结束时间 List<int>[,] result = new List<int>[13,13];//创建集合的二维数组 for (int i = 0; i < 13; i++)//对集合的二维数组进行初始化 { for (int j = 0; j < 13; j++) { result[i, j] = new List<int>(); } } for (int i = 0; i <s.Length ; i++)//两层for循环确定活动的时间区间 { for (int j = 0; j < i-1; j++) { List<int> list = new List<int>(); for (int number = 1; number < s.Length-1; number ++)//检测所有的活动是否在时间区间内 { if(s[number]>=f[j]&&f[number]<=s[i])//检测到活动在时间区间内,将活动存储起来 { list.Add(number); } } if(list.Count>0)//时间区间内有活动 { List<int> MaxCountAction = new List<int>(); int MaxCount = 0; foreach (var item in list) { int count = result[j, item].Count + result[item, i].Count + 1; if(MaxCount<count) { MaxCountAction.RemoveRange(0, MaxCountAction.Count);//清除集合中的数据 MaxCount = count; MaxCountAction.AddRange(result[j, item]); //把二维集合中的数据放入 MaxCountAction集合中 MaxCountAction.AddRange(result[item, i]); //把二维集合中的数据放入 MaxCountAction集合中 // MaxCountAction = result[j, item].Union<int>(result[item, i]).ToList<int>();//将 result[j, item]集合和result[item, i]集合中的数据放入 MaxCountAction中 MaxCountAction.Add(item); } } result[j,i] = MaxCountAction;//将j,i时间段的最大子数组存储在二维集合中 } } } foreach (var item in result[0, 12])//一天有12个活动的最多安排活动输出 { Console.WriteLine(item); } Console.ReadKey(); } } }