算法謎題2,手套選擇

題面描述

在抽屜裏有20隻手套。其中,5雙黑手套,3雙棕色手套和2雙灰手套。你只能在黑暗中挑手套,而且只能將手套挑出以後才能檢查顏色。最少要挑多少次才能知足如下條件
a> 至少挑出一雙顏色匹配的手套
b> 全部顏色的手套都至少挑出一雙匹配的。this


分析

總計有5 * 5 * 3 * 3 * 2 * 2 =900種狀態,單向圖,每一個頂點最多會與6個其餘頂點相連。遍歷圖能夠找到全部解,取最長路徑。code

可是否必定要這樣窮舉呢, 若是是由人類來計算,在反向最優的選擇下能夠將問題的描述轉換爲如下形式,而後在其結果的基礎上+ 1。blog

在知足如下條件的前提下,最多能夠挑多少次:
a> 不能挑出任何一雙顏色匹配的手套。 20 / 2 + 1 = 11
b> 至少有一種顏色的手套湊不齊一雙。 20 - 2 + 1 = 19string

實現

每一次都遍歷6種選擇,找一個知足條件的挑選方式,直到不能再挑爲止。it

class Program
{
    static void Main(string[] args)
    {
        //a:
        var count = Function((state) => !(state.HasBlackPair() || state.HasBlownPair() || state.HasGreyPair()));
        Console.WriteLine($"最少要挑{count}次才能至少挑出一雙顏色匹配的手套");

        //b:
        var a = Function((state) => !state.HasBlackPair());
        var b = Function((state) => !state.HasBlownPair());
        var c = Function((state) => !state.HasGreyPair());

        Console.WriteLine($"最少要挑{Math.Max(Math.Max(a,b),c)}次才能全部顏色的手套都至少挑出一雙匹配的");
        Console.ReadKey();
    }

    private static int Function(Func<State, bool> predicate)
    {
        int sum = 0;
        var state = new State();
        while (true)
        {
            if (state.TryAddOne(predicate))
            {
                sum++;
            }
            else
            {
                break;
            }
        }

        return sum + 1;
    }
}

public class State
{
    private int[] Data = new int[6];
    private int[] Max = new int[] { 5, 5, 3, 3, 2, 2 };

    public bool TryAddOne(Func<State,bool> predicate)
    {
        for (int i = 0; i < 6; i++)
        {
            if(Data[i] < Max[i])
            {
                Data[i]++;
                if (predicate(this))
                {
                    return true;
                }
                else
                {
                    Data[i]--;
                }
            }
        }

        return false;
    }

    public bool HasBlackPair()
    {
        return Data[0] > 0 && Data[1] > 0;
    }
    public bool HasBlownPair()
    {
        return Data[2] > 0 && Data[3] > 0;
    }
    public bool HasGreyPair()
    {
        return Data[4] > 0 && Data[5] > 0;
    }
}

相關文章
相關標籤/搜索