Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 过桥难题_Algorithm_Puzzle - Fatal编程技术网

Algorithm 过桥难题

Algorithm 过桥难题,algorithm,puzzle,Algorithm,Puzzle,四个人必须在晚上过桥。任何过桥的人,不管是一个人还是两个人,都必须随身携带手电筒。手电筒必须来回走动;它不能投掷,等等。每个人以不同的速度行走。一次穿越需要1分钟,另外2分钟,另外5分钟,最后10分钟。如果两个人一起交叉,他们必须以较慢的人的步速行走。没有诡计——男人们都从同一边开始,手电筒不能长距离发光,没有人能被抬着,等等 问题是他们能以什么最快的速度通过。我基本上是在寻找解决这类问题的一般方法。我的朋友告诉我,这可以用斐波那契级数来解,但这个解并不适用于所有的问题 请注意,这不是家庭作业。

四个人必须在晚上过桥。任何过桥的人,不管是一个人还是两个人,都必须随身携带手电筒。手电筒必须来回走动;它不能投掷,等等。每个人以不同的速度行走。一次穿越需要1分钟,另外2分钟,另外5分钟,最后10分钟。如果两个人一起交叉,他们必须以较慢的人的步速行走。没有诡计——男人们都从同一边开始,手电筒不能长距离发光,没有人能被抬着,等等

问题是他们能以什么最快的速度通过。我基本上是在寻找解决这类问题的一般方法。我的朋友告诉我,这可以用斐波那契级数来解,但这个解并不适用于所有的问题


请注意,这不是家庭作业。

17分钟-这是一个典型的MS问题

1,2 => 2 minutes passed.
1 retuns => 3 minutes passed.
5,10 => 13 minutes passed.
2 returns => 15 minutes passed.
1,2 => 17 minute passed.
总的来说,最大的问题/最慢的人应该总是放在一起,并且让最快的人有足够的行程,以便每次都能在不使用慢速资源的情况下将光线带回来。

17——这是一个非常常见的问题

->1-2=2
5,10=10(他们都不必返回)
1,2=2

都在另一边
总数=2+2+10+1+2=17


通常人们在第一次尝试时会得到19分

有()解决了这个问题的一般情况(在正式证明中)。

我会在Dice.com上放一个虚假的招聘广告来解决这个问题,然后在面试中问这个问题,直到有人答对为止。

在这么小的问题空间里,对所有可能性进行彻底的搜索是很简单的。广度或深度优先。这是一个简单的CS问题

根据维基百科,我更喜欢传教士和食人族的问题

这个谜题早在1981年就出现在《谜题和游戏的超级策略》一书中。在这个版本的拼图中,A、B、C和D分别需要5、10、20和25分钟才能完成,时间限制为60分钟

然而,这一问题在《你将如何移动富士山》一书中出现后便广为流行

这个问题可以推广到N个人,他们需要不同的时间过桥

下面的程序适用于一般N个人员及其时间

class Program
{
    public static int TotalTime(List<int> band, int n)
    {
        if (n < 3)
        {
            return band[n - 1];
        }
        else if (n == 3)
        {
            return band[0] + band[1] + band[2];
        }
        else
        {
            int temp1 = band[n - 1] + band[0] + band[n - 2] + band[0];
            int temp2 = band[1] + band[0] + band[n - 1] + band[1];

            if (temp1 < temp2)
            {
                return temp1 + TotalTime(band, n - 2);
            }
            else if (temp2 < temp1)
            {
                return temp2 + TotalTime(band, n - 2);
            }
            else
            {
                return temp2 + TotalTime(band, n - 2);
            }
        }
    }

    static void Main(string[] args)
    {
        // change the no of people crossing the bridge
        // add or remove corresponding time to the list
        int n = 4; 

        List<int> band = new List<int>() { 1, 2, 5, 10 };

        band.Sort();

        Console.WriteLine("The total time taken to cross the bridge is: " + Program.TotalTime(band, n));
        Console.ReadLine();
    }
}
类程序
{
公共静态整数总时间(列表带,整数n)
{
if(n<3)
{
返回带[n-1];
}
else如果(n==3)
{
返回频带[0]+频带[1]+频带[2];
}
其他的
{
int temp1=波段[n-1]+波段[0]+波段[n-2]+波段[0];
int temp2=波段[1]+波段[0]+波段[n-1]+波段[1];
如果(temp1
输出:

过桥总时间为:17

因为

int n=5;
List band=newlist(){1,2,5,10,12};
输出:

过桥的总时间是:25分钟

因为

int n=4;
List band=newlist(){5,10,20,25};
输出
过桥所需的总时间是:60

我用代数方法绘制了可能的解决方案,并以最快的时间得出了解决方案。用A,B,C,D的列表分配代数,其中A是最小的,D是最大的 最短时间的公式是B+A+D+B+B或3B+A+D 或者用罗嗦的话来说,第二快的乘以3的和加上最快和最慢的

看看这个项目,还有一个项目增加的问题。虽然我还没有经历过,但我猜公式仍然适用,只需将第二项乘以3的所有项相加,再加上除第二慢外的所有项的总和。 e、 g.因为4项是3 x秒+第一项和第四项。 然后5个项目是3x秒+第一、第三和第五。 我想用这个程序检查一下

另外,我刚才看了上面共享的pdf,所以对于更多的项目,它是 3 x第二个+最快+每个后续对中最慢的总和

查看优化解决方案的步骤,想法是 -右-对于右边的两个项目,最快的是第一和第二快, -左-然后加上最快返回的单个项目是最快的项目 -右-带上最慢的2个项目,这将只考虑最慢的项目,而忽略第二个最慢的项目。 -左-第二快的项目。 -最后右转-又是第一和第二快


所以再次总结=第二快的跑3次,最快的跑一次,最慢的跑第二慢。

一个简单的算法是:假设“N”是可以同时穿越的人数,一个人必须背着火炬穿越

  • 当将人从第一面移动到第二面时,应优先考虑“N”个最慢的步行者
  • 始终使用最快的步行者从第二面到第一面传递火炬
  • 当把人从第一面移到第二面时,要考虑下一步谁会把火炬带回来。如果下一步中火炬手的速度等于当前步骤中“N”个最慢步行者中的最快步行者,则选择“N”个最慢步行者,而不是“1”中给出的“N”个最慢步行者
  • 这是一个样品
    int n = 5; 
    List<int> band = new List<int>() { 1, 2, 5, 10, 12 };
    
    int n = 4; 
    List<int> band = new List<int>() { 5, 10, 20, 25 };
    
    @values = [1, 2, 5, 10]
    # @values = [1, 2, 5, 10, 20, 25, 30, 35, 40]
    @values.sort!
    @position = @values.map { |v| :first }
    @total = 0
    
    def send_people(first, second)
      first_time = @values[first]
      second_time = @values[second]
    
      @position[first] = :second
      @position[second] = :second
    
      p "crossing #{first_time} and #{second_time}"
    
      first_time > second_time ? first_time : second_time
    end
    
    def send_lowest
      value = nil
      @values.each_with_index do |v, i|
        if @position[i] == :second
          value = v
          @position[i] = :first
          break
        end
      end
    
      p "return #{value}"
      return value
    end
    
    
    def highest_two
      first = nil
      second = nil
    
      first_arr = @position - [:second]
    
      if (first_arr.length % 2) == 0
        @values.each_with_index do |v, i|
          if @position[i] == :first
            first = i unless first
            second = i if !second && i != first
          end
    
          break if first && second
        end
      else
        @values.reverse.each_with_index do |v, i|
          real_index = @values.length - i - 1
          if @position[real_index] == :first
            first = real_index unless first
            second = real_index if !second && real_index != first
          end
    
          break if first && second
        end
      end
    
      return first, second
    end
    
    #we first send the first two
    @total += send_people(0, 1)
    #then we get the lowest one from there
    @total += send_lowest
    #we loop through the rest with highest 2 always being sent
    while @position.include?(:first)
      first, second = highest_two
      @total += send_people(first, second)
      @total += send_lowest if @position.include?(:first)
    end
    
    p "Total time: #{@total}"
    
    @values = [1,2,5,10]
    # @values = [1,2,5,10,20,25]
    @left = @values.sort
    @right = []
    @total_time = 0
    
    def trace(moving)
      puts moving
      puts "State: #{@left} #{@right}"
      puts "Time: #{@total_time}"
      puts "-------------------------"
    end
    
    # move right the fastest two
    def move_fastest_right!
      fastest_two = @left.shift(2)
      @right = @right + fastest_two
      @right = @right.sort
      @total_time += fastest_two.max
      trace "Moving right: #{fastest_two}"
    end
    
    # move left the fastest runner
    def move_fastest_left!
      fastest_one = @right.shift
      @left << fastest_one
      @left.sort!
      @total_time += fastest_one
      trace "Moving left: #{fastest_one}"
    end
    
    # move right the slowest two
    def move_slowest_right!
      slowest_two = @left.pop(2)
      @right = @right + slowest_two
      @right = @right.sort
      @total_time += slowest_two.max
      trace "Moving right: #{slowest_two}"
    end
    
    def iterate!
      move_fastest_right!
      return if @left.length == 0
    
      move_fastest_left!
      move_slowest_right!
      return if @left.length == 0
    
      move_fastest_left!
    end
    
    puts "State: #{@left} #{@right}"
    puts "-------------------------"
    while @left.length > 0
      iterate!
    end
    
    State: [1, 2, 5, 10] []
    -------------------------
    Moving right: [1, 2]
    State: [5, 10] [1, 2]
    Time: 2
    -------------------------
    Moving left: 1
    State: [1, 5, 10] [2]
    Time: 3
    -------------------------
    Moving right: [5, 10]
    State: [1] [2, 5, 10]
    Time: 13
    -------------------------
    Moving left: 2
    State: [1, 2] [5, 10]
    Time: 15
    -------------------------
    Moving right: [1, 2]
    State: [] [1, 2, 5, 10]
    Time: 17
    -------------------------
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace RiverCrossing_Problem
    {
        class Program
        {
            static void Main(string[] args)
            {
                Dictionary<string, int> Side1 = new Dictionary<string, int>();
                Dictionary<string, int> Side2 = new Dictionary<string, int>();
    
                Console.WriteLine("Enter number of persons");
                int n = Convert.ToInt32(Console.ReadLine());
    
                Console.WriteLine("Enter the name and time taken by each");
    
                for(int a =0; a<n; a++)
                {
                    string tempname = Console.ReadLine();
                    int temptime = Convert.ToInt32(Console.ReadLine());
                    Side1.Add(tempname, temptime);
                }
    
                Console.WriteLine("Shortest time and logic:");
                int totaltime = 0;
                int i = 1;
                do
                {
                    KeyValuePair<string, int> low1, low2, high1, high2;
                    if (i % 2 == 1)
                    {
                        LowestTwo(Side1, out low1, out low2);
                        Console.WriteLine("{0} and {1} goes from side 1 to side 2, time taken = {2}", low1.Key, low2.Key, low2.Value);
                        Side1.Remove(low2.Key);
                        Side1.Remove(low1.Key);
                        Side2.Add(low2.Key, low2.Value);
                        Side2.Add(low1.Key, low1.Value);
                        totaltime += low2.Value;
    
                        low1 = LowestOne(Side2);
                        Console.WriteLine("{0} comes back to side 1, time taken = {1}", low1.Key, low1.Value);
                        totaltime += low1.Value;
                        Side1.Add(low1.Key, low1.Value);
                        Side2.Remove(low1.Key);
                        i++;
                    }
                    else
                    {
                        HighestTwo(Side1, out high1, out high2);
                        Console.WriteLine("{0} and {1} goes from side 1 to side 2, time taken = {2}", high1.Key, high2.Key, high1.Value);
                        Side1.Remove(high1.Key);
                        Side1.Remove(high2.Key);
                        Side2.Add(high1.Key, high1.Value);
                        Side2.Add(high2.Key, high2.Value);
                        totaltime += high1.Value;
    
                        low1 = LowestOne(Side2);
                        Console.WriteLine("{0} comes back to side 1, time taken = {1}", low1.Key, low1.Value);
                        Side2.Remove(low1.Key);
                        Side1.Add(low1.Key, low1.Value);
                        totaltime += low1.Value;
                        i++;
                    }
                } while (Side1.Count > 2);
    
                KeyValuePair<string, int> low3, low4;
                LowestTwo(Side1, out low3, out low4);
                Console.WriteLine("{0} and {1} goes from side 1 to side 2, time taken = {2}", low3.Key, low4.Key, low4.Value);
                Side2.Add(low4.Key, low4.Value);
                Side2.Add(low3.Key, low3.Value);
                totaltime += low4.Value;
    
                Console.WriteLine("\n");
                Console.WriteLine("Total Time taken = {0}", totaltime);
    
            }
    
            public static void LowestTwo(Dictionary<string, int> a, out KeyValuePair<string, int> low1, out KeyValuePair<string, int> low2)
            {
                Dictionary<string, int> b = a;
                low1 = b.OrderBy(kvp => kvp.Value).First();
                b.Remove(low1.Key);
                low2 = b.OrderBy(kvp => kvp.Value).First();
            }
    
            public static void HighestTwo(Dictionary<string,int> a, out KeyValuePair<string,int> high1, out KeyValuePair<string,int> high2)
            {
                Dictionary<string, int> b = a;
                high1 = b.OrderByDescending(k => k.Value).First();
                b.Remove(high1.Key);
                high2 = b.OrderByDescending(k => k.Value).First();
            }
    
            public static KeyValuePair<string, int> LowestOne(Dictionary<string,int> a)
            {
                Dictionary<string, int> b = a;
                return b.OrderBy(k => k.Value).First();
            }
        }
    }
    
    Enter number of persons
    7
    Enter the name and time taken by each
    A
    2
    B
    5
    C
    3
    D
    7
    E
    9
    F
    4
    G
    6
    Shortest time and logic:
    A and C goes from side 1 to side 2, time taken = 3
    A comes back to side 1, time taken = 2
    E and D goes from side 1 to side 2, time taken = 9
    C comes back to side 1, time taken = 3
    A and C goes from side 1 to side 2, time taken = 3
    A comes back to side 1, time taken = 2
    G and B goes from side 1 to side 2, time taken = 6
    C comes back to side 1, time taken = 3
    A and C goes from side 1 to side 2, time taken = 3
    A comes back to side 1, time taken = 2
    A and F goes from side 1 to side 2, time taken = 4
    
    
    Total Time taken = 40