贪心算法并不能让问题的每一个情况都实现最优解

 

活动选择问题

 

使用穷举法

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();
        }
    }
}

 

posted on 2019-08-26 19:46  晴耕--雨读  阅读(431)  评论(0编辑  收藏  举报