【问题标题】:Sum of 5 numbers = 100 [duplicate]5个数字的总和= 100 [重复]
【发布时间】:2026-02-22 05:40:01
【问题描述】:

所以,给你 10 个数字,你应该从中选择 5 个数字,这样总和就是 100。

现在,我显然尝试使用程序来解决它,并通过五个循环得到了明显的解决方案。但我只是想知道有没有有效的方法来做到这一点?

这是显而易见的先生:

        static void Main(string[] args)
        {
            int[] a = { 2, 6, 10, 14, 18, 22, 26, 30, 34, 38 };
            for (int f = 0; f < a.Length - 4; f++)
            {
                for (int s = f+1; s < a.Length - 3; s++)
                {
                    for (int t = s+1; t < a.Length - 2; t++)
                    {
                        for (int fr = t + 1; fr < a.Length - 1; fr++)
                        {
                            for (int ft = fr + 1; ft < a.Length; ft++)
                            {
                                int sum = a[f] + a[s] + a[t] + a[fr] + a[ft];
                                Console.WriteLine(sum);
                                if (sum == 100)
                                {
                                    Console.WriteLine("---------------------------------------");
                                    Console.WriteLine(a[f]);
                                    Console.WriteLine(a[s]);
                                    Console.WriteLine(a[t]);
                                    Console.WriteLine(a[fr]);
                                    Console.WriteLine(a[ft]);
                                    Console.WriteLine("---------------------------------------");
                                }
                            }

                        }
                    }
                }
            }
            Console.ReadLine();
        }

【问题讨论】:

  • 你忘了python标签..
  • 似乎是动态编程的工作。也许是背包问题的一种变体?
  • 可能重复? *.com/questions/4632322/… 几乎涵盖了这门语言中的所有语言,虽然我没有看到 C++
  • 如果您标记每种语言,您可能只想用算法标记它并使其与语言无关。
  • 我看不出那些势利的 cmets 的原因,这是一个通用的 CS 问题,与语言无关。对 OP:这是一个 NP-Complete 问题,无论你用什么方法解决它,你都会得到指数级的复杂性。当然,除非你使用某种近似算法。

标签: algorithm language-agnostic logic


【解决方案1】:

您可以使用组合。看看这个问题: creating all possible k combinations of n items in C++

在这种情况下,您有 n 个数字和 k 个数字索引可供选择。

这应该会减少迭代次数。

【讨论】:

    【解决方案2】:

    这里有一些优化的想法:

    • 如果所有数字都是正数,您可以跳过内部循环,总和已经 >= 100
    • 您可以通过计算每个循环中的部分和来减少计算(运行内部循环时外部循环的值不会改变)。
    • 只计算一次a.Length 并存储它,因为这个值永远不会改变

      static void Main(string[] args)
      {
          int[] a = { 2, 6, 10, 14, 18, 22, 26, 30, 34, 38 };
          int lenA=a.Length;
          int alenMinus4=lenA-4,
          int alenMinus3=lenA-3,
          int alenMinus2=lenA-2,
          int alenMinus1=lenA-1,
      
          for (int f = 0; f < alenMinus4; f++)
          {   int sum1=a[f];
              if(sum1>100)
              { f=alenMinus4;
              }
              else
              {   for (int s = f+1; s < alenMinus3; s++)
                  {   int sum2=sum1+ a[s];
                      if(sum2>100)
                      { s=alenMinus3;
                      }
                      else
                      {   for (int t = s+1; t < alenMinus2; t++)
                          {   int sum3=sum2+ a[t];
                              if(sum3>100)
                              { t=alenMinus2;
                              }
                              else
                              {   for (int fr = t + 1; fr < alenMinus1; fr++)
                                  {   int sum4=sum3+ a[fr];
                                      if(sum4>100)
                                      { fr=alenMinus1;
                                      }
                                      else
                                      {  for (int ft = fr + 1; ft < lenA; ft++)
                                          {   int sum = sum4 + a[ft];
                                              Console.WriteLine(sum);
                                              if (sum == 100)
                                              {   Console.WriteLine("---------------------------------------");       
                                                  Console.WriteLine(a[f]);
                                                  Console.WriteLine(a[s]);
                                                  Console.WriteLine(a[t]);
                                                  Console.WriteLine(a[fr]);
                                                  Console.WriteLine(a[ft]);
                                                  Console.WriteLine("---------------------------------------");
          }   }   }   }   }   }   }   }   }   }
          Console.ReadLine();
      }
      

    【讨论】:

    • 希望编译器可以对 2) 和 3) 进行优化,并且只有 1) 需要任何新代码。
    • @Marc Glisse:编译器可能 [我不会指望它] 进行优化 3) [如果它足够聪明,可以检测到这永远不会改变]。我敢打赌,编译器不会检测到总和的部分 a[f] + a[s] + a[t] + a[fr] + a[ft] 可以移动到外循环。正如您所同意的那样,1) 优化将最大程度地提高速度,需要人工更改代码。