【问题标题】:Dividing up a long list of numbers and figuring out the minimum summation of each chunk划分一长串数字并计算出每个块的最小总和
【发布时间】:2016-09-01 02:16:19
【问题描述】:

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

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

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

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

等等。 . .等等 。 . .

我的目标是计算出这三天的“最短”步行距离。因此,在此示例中,第 1 天的 11 和第 2 天的 26 和第 3 天的 22 将给出最大值 26,而 26 实际上是最小值 - 没有比这更好的了。

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

但是,我不太清楚如何将列表元素划分为 3,即天数。如果是四个,我每天可以有四个距离任意数量的块。然后将所有划分的元素相加,看看哪个最大值是最小值。

我很感激此时这对我来说可能是一个太大的问题(我几乎可以理解我在下面放置的程序)但我想知道是否有人可以帮助我理解这一点并帮助我编写一个可以处理任意天数和步行阶段的函数。

到目前为止,我所能产生的只是一个可以打印这 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();
        }
    }

【问题讨论】:

  • 你的程序的目标是什么?看了几遍你的描述,我还是一头雾水。输入:整数数组(跋涉距离),所需的组数(天)和每组所需的 # 数量(每天的跋涉次数),输出:每组中的最小总和(距离总和) ) ?
  • 是否预计 # 天 * # 步行阶段 = # 提供的距离? (即在您的示例中 3 天 * 2 次跋涉 = 我必须获得 6 次距离)---并且不能多次使用距离(从您的示例中假设)
  • 为什么不对步行阶段列表进行排序,然后将其分成两个数组,一个包含前半部分,一个包含后半部分。然后从相反的两端添加它们List&lt;int&gt; newList = new List&lt;int&gt;(); for(int i = 0, j = array2.Length - 1; i &lt; array1.Length; i++, j--) {newList.Add(array1[i] + array2[j]);}这不会得到你想要的吗?
  • 我对这个问题的所有限制感到困惑。如果它只能按照 11、16、5、5、12、10 的顺序排列,那这有什么意义呢?如果您可以分割步行距离,和/或重新排列它们,那么它们如何分割的规定是什么?
  • 好的,所以您正在寻找三天内所有可能的连续步行距离组合中的最低最大值?

标签: c#


【解决方案1】:

这个问题可以通过dynamic programming解决。这是我用自上而下的方法编写的代码:

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)

【讨论】:

  • 这是天才!太感谢了。目前这有点超出我的想象,但我想知道您是否知道快速开始学习动态编程的好地方?干杯
  • 您好,我仍然很难完全理解这一点,所以我想知道您能否再解释一下,以及一些小东西,例如为什么return int.MaxValue?跨度>
  • return int.MaxValue 是为了惩罚睡眠过多 :-) 也就是说,如果您在跋涉中途睡了最后一晚,这是不正确的解决方案。另一种写法是检查我们是否只剩下 1 天,然后返回数组中剩余天数的总和。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-03-07
  • 1970-01-01
  • 2012-01-10
  • 1970-01-01
  • 2021-02-20
  • 1970-01-01
  • 2018-08-09
相关资源
最近更新 更多