把一长串数字分开,算出每个数字块的最小和

本文关键字:数字 | 更新日期: 2023-09-27 18:05:13

我一直在编写三个小程序,它们提取给定字符串(甚至是整数列表)的所有子字符串以及它们元素的所有不同组合。我现在明白了……

我开始这样做的目的(最初)是想看看我是否能通过学习这些程序来解决一个难题。这是一个谜题:

假设我正在徒步旅行,我有6步行距离{ 11, 16, 5, 5, 12, 10 },我想在3天内完成。所以,我可以在第一天跑11公里和16公里,在第二天跑5公里和5公里,最后在第三天跑12公里和10公里。

也许我在第1天只能跑11公里,第16和第5天只能跑5公里,第3天只能跑12和10公里。

等等。等等

我的目标是算出这三天的"最小"步行距离。所以,在这个例子中,第1天11个,第2天26个,第3天22个,最大值是26,而26实际上是最小值——没有比这更好的了。

无论我选择三个块(天)的哪个组合,每天的步行距离都不会小于26。例如,如果我选择第1天为11+16,第2天为5+5,第3天为12+10,那么我看到的最大值是27。

然而,我不太明白如何在3中划分列表元素,这是天数。如果是4,我可以有4个块,每天有任意数量的距离。然后把所有被分割的元素加起来,看看哪个最大值是最小值。

我知道这对我来说可能太大了(我只能理解下面的程序),但我想知道是否有人可以帮助我理解这一点,并帮助我编写一个可以处理任何天数和行走阶段的函数。

到目前为止,我所能生成的只是一个函数,它可以打印这6个行走阶段的所有子列表和组合…

    static void Main(string[] args)
    {
        string str = Console.ReadLine();
        for (int i = 1; i <= str.Length; i++)
        {
            for (int j = 0; j <= (str.Length - i); j++)
            {
                string subStr = str.Substring(j, i);
                Console.WriteLine(subStr);
            }
        }
        Console.ReadLine();
    }

    static void Main(string[] args)
    {
        List<int> list = new List<int>() { 11, 16, 5, 5, 12, 10 };
        for (int i = 0; i <= list.Count-1; i++)
        {
            for (int j = 0; j <= list.Count-i; j++)
            {
                string subList = string.Concat( list.GetRange(i, j) );
                Console.WriteLine(subList);
            }
        }
        Console.ReadLine();
    }

    static void Main(string[] args)
    {
        GetCombination( new List<int> { 11, 16, 5, 5, 12, 10 } );
        Console.ReadLine();
    }
    static void GetCombination( List<int> list )
    {
        double count = Math.Pow(2, list.Count);
        for (int i = 1; i <= (count-1); i++)
        {
            string str = Convert.ToString(i, 2).PadLeft(list.Count, '0');
            for (int j = 0; j < str.Length; j++)
            {
                if ( str[j] == '1' )
                {
                    Console.Write( list[j] );
                }
            }
            Console.WriteLine();
        }
    }

把一长串数字分开,算出每个数字块的最小和

这个问题可以通过动态规划来解决。下面是我使用自顶向下方法编写的代码:

class Program
{
    static void Main(string[] args)
    {
        int[] array = { 11, 16, 5, 5, 12, 10 };
        // change last parameter to the number or days
        int min = MinDistance(array, 0, 0, 3); 
        Console.WriteLine(min);
    }
    static int MinDistance(int[] array, int day, int prevDayDistance, int daysLeft)
    {
        if (day == array.Length)
        {
            return prevDayDistance;
        }
        if (daysLeft == 0)
        {
            return int.MaxValue;
        }
        // Keep walking.
        int keepWalkResult = MinDistance(array, day + 1, prevDayDistance + array[day], daysLeft);
        // Postpone it to the next day.
        int sleepResult = MinDistance(array, day, 0, daysLeft - 1);
        // Choose the best solution.
        return Math.Min(keepWalkResult, Math.Max(prevDayDistance, sleepResult));
    }
}

对于大的输入数组,您可以考虑将MinDistance结果缓存为三元组(day,prevDayDistance,daysLeft)