当前位置:编程学习 > C#/ASP.NET >>

如何用最少的菜满足大家的口味?

有这么个场景,有一帮同事去吃饭,每个同事都写出自己喜欢吃的菜,如何从这些菜单里得到一个最终下锅的菜单呢?
下锅菜单的要求:
1.菜最少
2.满足各同事的口味
3.求算法

代码描述:

using System;
using System.Collections.Generic;

namespace ConsoleApplication1
{

    class Program
    {
        enum Menu : byte
        {
            麻婆豆腐 = 1,
            红烧排骨 = 2,
            地三鲜 = 3,
            干煸四季豆 = 4,
            红烧牛肉 = 5
        }

        static void Main(string[] args)
        {
            // 场景一
            List<Menu> menu1 = new List<Menu>() { Menu.麻婆豆腐, Menu.红烧排骨, Menu.地三鲜 };
            List<Menu> menu2 = new List<Menu>() { Menu.麻婆豆腐, Menu.地三鲜, Menu.红烧牛肉 };
            List<Menu> menu3 = new List<Menu>() { Menu.红烧排骨, Menu.干煸四季豆 };
            List<Menu> menuCook1 = new List<Menu>() { Menu.麻婆豆腐, Menu.红烧排骨, Menu.干煸四季豆 };
            // 最终,要下锅的菜单有:麻婆豆腐,红烧排骨,干煸四季豆
            // 虽然麻婆豆腐,红烧排骨,地三鲜重复了,但只取一个菜就行

            // 场景二
            List<Menu> menu4 = new List<Menu>() { Menu.麻婆豆腐, Menu.红烧排骨, Menu.地三鲜 };
            List<Menu> menu5 = new List<Menu>() { Menu.红烧排骨, Menu.地三鲜, Menu.红烧牛肉 };
            List<Menu> menu6 = new List<Menu>() { Menu.红烧排骨, Menu.干煸四季豆 };
            List<Menu> menu7 = new List<Menu>() { Menu.麻婆豆腐, Menu.红烧排骨, Menu.地三鲜, Menu.干煸四季豆, Menu.红烧牛肉 };
            List<Menu> menuCook2 = new List<Menu>() { Menu.红烧排骨 };
            // 最终,要下锅的菜单有:红烧排骨,因为四个同事开出的菜单里都有红烧排骨

            Console.ReadKey();
        }
    }
}
--------------------编程问答-------------------- 火锅

乱炖 --------------------编程问答-------------------- 自助餐
--------------------编程问答-------------------- 只有一个菜下锅,那要完全照顾所有人是不可能的。
所以只能照顾大多数人的口味,选择出现次数最多的菜下锅,当然,一个人的菜单中相同的菜只能算出现一次。

--------------------编程问答-------------------- 这个题目有意思,坐等高手 --------------------编程问答-------------------- 我的想法是:点的最多的菜>判断是否有人没点这道菜>然后再取没点这道菜的人所点的那些菜中点的最多的菜; --------------------编程问答-------------------- 用个集合记录下
 Dictionary<菜名,出现次数>
出现次数多的肯定大众化
如果出现次数最多的菜跟人的个数相等,那就取一个菜
否在像第一个场景取钱三 --------------------编程问答-------------------- 楼主的语言就不能准确一点吗?
1,菜最少
2.满足各同事的口味

我脑补一下,是不是,
1,所有人至少要有一份自己点过的菜?
2,满足1的情况下,菜最少

靠,分析了下场景一,
1,每个人点菜数目不确定?
2,有四季豆满足第三人,却没有牛肉满足第二人?

这需求我真心没法理解,你继续等大神吧。
--------------------编程问答-------------------- 1、不对,不符合菜最少的标准啊
符合标准应该是这样的哇
麻婆豆腐 + 红烧排骨(或者 干煸四季豆) 
或者
地三鲜  +  干煸四季豆 --------------------编程问答-------------------- 还有
红烧排骨 + 地三鲜(或者 红烧牛肉) --------------------编程问答-------------------- 嗯,场景一的 menuCook1 是错误的,多了一菜 --------------------编程问答-------------------- 其实就是图论的应用,图论查二部图
--------------------编程问答-------------------- 把人作为一个矩阵的行,菜作为矩阵的列,凡是某个菜能满足某个人,相应的位置为1,否则为0
扎好找到满足所有人的菜,就是对这个矩阵的运算。 --------------------编程问答-------------------- 你们说的好复杂,我只会使用最笨的排除法,先找出最多人点的菜,然后删除人,再加,再删除

using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApplication1
{

    class Program
    {
        enum Menu : byte
        {
            麻婆豆腐 = 1,
            红烧排骨 = 2,
            地三鲜 = 3,
            干煸四季豆 = 4,
            红烧牛肉 = 5
        }

        static void Main(string[] args)
        {
            List<Menu> menu1 = new List<Menu>() { Menu.麻婆豆腐, Menu.红烧排骨, Menu.地三鲜 };
            List<Menu> menu2 = new List<Menu>() { Menu.干煸四季豆, Menu.红烧牛肉, Menu.麻婆豆腐 };
            List<Menu> menu3 = new List<Menu>() { Menu.红烧排骨, Menu.地三鲜, Menu.干煸四季豆 };
            List<Menu> menu4 = new List<Menu>() { Menu.红烧牛肉 }; 

            Dictionary<Menu, Byte> dic1 = new Dictionary<Menu, Byte>();
            List<List<Menu>> listMenu = new List<List<Menu>>();
            List<Menu> menuCook = new List<Menu>();

            listMenu.Add(menu1);
            listMenu.Add(menu2);
            listMenu.Add(menu3);
            listMenu.Add(menu4);

            Byte count;
            foreach (List<Menu> itemMenu in listMenu)
            {
                foreach (Menu item in itemMenu)
                {
                    if (dic1.TryGetValue(item, out count))
                    {
                        dic1[item]++;
                    }
                    else
                    {
                        dic1.Add(item, 1);
                    }
                }
            }

            // 排序
            var dic2 = dic1.OrderByDescending(s => s.Value);

            foreach (KeyValuePair<Menu, Byte> dicItem  in dic2)
            {
                bool b = true;

                if (menuCook.Count <= 0)
                {
                    menuCook.Add(dicItem.Key);
                }

                if (listMenu.Count > 0)
                {
                    for (int i = listMenu.Count - 1; i >= 0; i--)
                    {
                        foreach (Menu menu in listMenu[i])
                        {
                            if (menuCook.Contains(menu))
                            {
                                b = false;
                                listMenu.RemoveAt(i);
                                break;
                            }
                        }
                    }

                    if (b)
                    {
                        menuCook.Add(dicItem.Key);
                    }
                }
            }

            foreach (Menu menu in menuCook)
            {
                Console.WriteLine(menu);
            }

            Console.ReadKey();
        }
    }
}
--------------------编程问答--------------------
引用 13 楼 u010791717 的回复:
你们说的好复杂,我只会使用最笨的排除法,先找出最多人点的菜,然后删除人,再加,再删除

using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApplication1
{

    class Program
    {
        enum Menu : byte
        {
            麻婆豆腐 = 1,
            红烧排骨 = 2,
            地三鲜 = 3,
            干煸四季豆 = 4,
            红烧牛肉 = 5
        }

        static void Main(string[] args)
        {
            List<Menu> menu1 = new List<Menu>() { Menu.麻婆豆腐, Menu.红烧排骨, Menu.地三鲜 };
            List<Menu> menu2 = new List<Menu>() { Menu.干煸四季豆, Menu.红烧牛肉, Menu.麻婆豆腐 };
            List<Menu> menu3 = new List<Menu>() { Menu.红烧排骨, Menu.地三鲜, Menu.干煸四季豆 };
            List<Menu> menu4 = new List<Menu>() { Menu.红烧牛肉 }; 

            Dictionary<Menu, Byte> dic1 = new Dictionary<Menu, Byte>();
            List<List<Menu>> listMenu = new List<List<Menu>>();
            List<Menu> menuCook = new List<Menu>();

            listMenu.Add(menu1);
            listMenu.Add(menu2);
            listMenu.Add(menu3);
            listMenu.Add(menu4);

            Byte count;
            foreach (List<Menu> itemMenu in listMenu)
            {
                foreach (Menu item in itemMenu)
                {
                    if (dic1.TryGetValue(item, out count))
                    {
                        dic1[item]++;
                    }
                    else
                    {
                        dic1.Add(item, 1);
                    }
                }
            }

            // 排序
            var dic2 = dic1.OrderByDescending(s => s.Value);

            foreach (KeyValuePair<Menu, Byte> dicItem  in dic2)
            {
                bool b = true;

                if (menuCook.Count <= 0)
                {
                    menuCook.Add(dicItem.Key);
                }

                if (listMenu.Count > 0)
                {
                    for (int i = listMenu.Count - 1; i >= 0; i--)
                    {
                        foreach (Menu menu in listMenu[i])
                        {
                            if (menuCook.Contains(menu))
                            {
                                b = false;
                                listMenu.RemoveAt(i);
                                break;
                            }
                        }
                    }

                    if (b)
                    {
                        menuCook.Add(dicItem.Key);
                    }
                }
            }

            foreach (Menu menu in menuCook)
            {
                Console.WriteLine(menu);
            }

            Console.ReadKey();
        }
    }
}

你选用最多的菜,最后有可能找不到解。
补充:.NET技术 ,  C#
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,