C++ C++;

C++ C++;,c++,recursion,combinatorics,pascals-triangle,C++,Recursion,Combinatorics,Pascals Triangle,我构建了递归函数来计算Pascal的三角形值 有没有办法优化它 关于帕斯卡三角形的简短提示:C(n,k)=C(n-1,k-1)+C(n-1,k) 我的代码是: int Pascal(int n, int k) { if (k == 0) return 1; if (n == 0) return 0; return Pascal(n - 1, k - 1) + Pascal(n - 1, k); } 我看到的低效率是,它将一些值存储了两次。 例子: C(6,2)=C(5,1)+C(5,2) C(

我构建了递归函数来计算Pascal的三角形值

有没有办法优化它

关于帕斯卡三角形的简短提示:C(n,k)=C(n-1,k-1)+C(n-1,k) 我的代码是:

int Pascal(int n, int k) {
if (k == 0) return 1;
if (n == 0) return 0;
return Pascal(n - 1, k - 1) + Pascal(n - 1, k);
}
我看到的低效率是,它将一些值存储了两次。 例子: C(6,2)=C(5,1)+C(5,2) C(6,2)=C(4,0)+C(4,1)+C(4,1)+C(4,2) 它将调用C(4,1)两次

你知道如何优化这个功能吗


感谢

保留以前返回的结果表(按其
n
k
值索引);这里使用的技术是。您还可以将递归更改为迭代,并使用填充一个数组,该数组包含小于您试图计算的值的
n
k
三角形,然后从中仅获取一个元素。

以下例程将使用递归定义和记忆计算n-choose-k。该程序非常快速准确:

inline unsigned long long n_choose_k(const unsigned long long& n,
                                     const unsigned long long& k)
{
   if (n  < k) return 0;
   if (0 == n) return 0;
   if (0 == k) return 1;
   if (n == k) return 1;
   if (1 == k) return n;

   typedef unsigned long long value_type;

   class n_choose_k_impl
   {
   public:

      n_choose_k_impl(value_type* table,const value_type& dimension)
      : table_(table),
      dimension_(dimension / 2)
      {}

      inline value_type& lookup(const value_type& n, const value_type& k)
      {
         const std::size_t difference = static_cast<std::size_t>(n - k);
         return table_[static_cast<std::size_t>((dimension_ * n) + ((k < difference) ? k : difference))];
      }

      inline value_type compute(const value_type& n, const value_type& k)
      {
         // n-Choose-k = (n-1)-Choose-(k-1) + (n-1)-Choose-k
         if ((0 == k) || (k == n))
            return 1;
         value_type v1 = lookup(n - 1,k - 1);
         if (0 == v1)
            v1 = lookup(n - 1,k - 1) = compute(n - 1,k - 1);
         value_type v2 = lookup(n - 1,k);
         if (0 == v2)
            v2 = lookup(n - 1,k) = compute(n - 1,k);
         return v1 + v2;
      }

      value_type* table_;
      const value_type dimension_;
   };

   static const std::size_t static_table_dim = 100;
   static const std::size_t static_table_size = static_cast<std::size_t>((static_table_dim * static_table_dim) / 2);
   static value_type static_table[static_table_size];
   static bool static_table_initialized = false;

   if (!static_table_initialized && (n <= static_table_dim))
   {
      std::fill_n(static_table,static_table_size,0);
      static_table_initialized = true;
   }

   const std::size_t table_size = static_cast<std::size_t>(n * (n / 2) + (n & 1));

   unsigned long long dimension = static_table_dim;
   value_type* table = 0;

   if (table_size <= static_table_size)
      table = static_table;
   else
   {
      dimension = n;
      table = new value_type[table_size];
      std::fill_n(table,table_size,0LL);
   }

   value_type result = n_choose_k_impl(table,dimension).compute(n,k);

   if (table != static_table)
      delete [] table;

   return result;
}
inline unsigned long n\u选择k(const unsigned long long&n,
常量无符号长(&k)
{
如果(n如果(!static_table_initialized&&(n),我认为这是递归的一个典型问题,而不是重新计算这些值,您应该将它们存储在“表”中与数据结构类似,然后不重新运行函数,而是在表中查找。正如您所确定的,使用相同值调用函数的重叠浪费了处理时间(经典的过程时间/内存权衡)。我没有一个直接的解决方案,但你肯定有正确的想法。一个小的优化是当n==k时返回1,这将提高速度,从
O(Sum(C(n,I),对于I,从0到k))
O(C(n,k))
@shaunhusain谢谢大家,我也会分配一些内存!@Neil好主意。