动态编程语言静态编程语言
介绍 (Introduction)
Today in this tutorial, we are going to discuss the concept of Dynamic Programming. It is a much more optimal approach to programming.
今天,在本教程中,我们将讨论动态编程的概念。 这是一种更好的编程方法。
动态编程 (Dynamic Programming)
Theoretically, Dynamic Programming is a problem-solving technique that solves a problem by dividing it into sub-problems. When the sub-problems are same and dependent, Dynamic programming comes into the picture.
从理论上讲, 动态编程是一种解决问题的技术,它通过将问题分成子问题来解决。 当子问题相同且相互依赖时,动态编程就会出现。
It is very similar to the Divide and Conquer approach to problem-solving. But in some cases, the Divide and Conquer technique may perform some operations or tasks multiple times (increasing time complexity).
它与解决问题的“ 分而治之”方法非常相似。 但是在某些情况下,分而治之技术可能会多次执行某些操作或任务(增加时间复杂度)。
Hence, the Dynamic Programming method (DP) is normally used to optimize a specific problem.
因此,动态编程方法(DP)通常用于优化特定问题。
Further, DP follows the Principle of Optimality which states that for an optimal sequence of decisions, each sub-sequence must also be optimal.
此外, DP遵循最优性原则,该原则指出,对于最佳决策序列,每个子序列也必须是最优的。
示例–使用DP的斐波那契 (Example – Fibonacci Using DP )
Now that we have discussed the basic concept of Dynamic Programming, let us look at how to solve a problem using this method.
现在我们已经讨论了动态编程的基本概念,让我们看看如何使用这种方法解决问题。
In the example below, we try to calculate the number at the position n
(user input) in the Fibonacci series.
在下面的示例中,我们尝试计算斐波那契数列中位置n
(用户输入)处的数字。
As you know, a Fibonacci series looks like this,
如您所知,斐波那契数列看起来像这样,
0, 1, 1, 2, 3, 5, 8 … upto n terms.
0、1、1、2、3、5、8…最多n个词。
Here, the starting two digits are 0 and 1.
在这里,起始两位数字是0和1 。
Let’s write a program to automatically find the right number at a specific point in the Fibonacci sequence based on the user input.
让我们编写一个程序,根据用户输入在斐波那契数列的特定点自动找到正确的数字。
Using Recursion(in C):
使用递归(在C中):
#include<stdio.h>
//fibonacci calculating function
int fibo(int n)
{
if(n==1)
return 0;
else if(n==2)
return 1;
else
return fibo(n-1) + fibo(n-2);
}
int main()
{
int n,res;
printf("Enter n : ");
scanf("%d",&n);
res=fibo(n);
printf("fibo(%d) = %d",n,res);
return 0;
}
Output:
输出 :
Enter n : 5
fibo(5) = 3
![Fibo2](https://cdn.journaldev.com/wp-content/uploads/2020/04/fibo2-1024x768.png)
So as you can see, in our above example taking n=5
, recursion breaks the problem into sub-problems using recursive calls.
如您所见,在我们上面的示例中,使用n=5
,递归使用递归调用将问题分解为子问题。
Take a closer look, notice that in this case, fibo(3)
is calculated twice. Which then breaks down to two recursive calls for fibo(1)
and fibo(2)
. They have values 0 and 1 respectively. Finally, we get our desired output i.e., fibo(5) = 3
.
仔细观察一下,请注意,在这种情况下, fibo(3)
是两次计算的。 然后将其分解为对fibo(1)
和fibo(2)
两个递归调用。 它们的值分别为0和1 。 最后,我们得到所需的输出,即fibo(5) = 3
。
Applying DP(in C):
应用DP(在C中):
#include<stdio.h>
int fibo_series[100];
void set_zero()
{
int i;
for (i = 1; i <= 100; i++)
fibo_series[i] = 0;
}
//fibonacci calculating function
int fibo(int n)
{
if (fibo_series[n] == 0)
{
if (n <= 1)
fibo_series[n] = n;
else
fibo_series[n] = fibo(n - 1) + fibo(n - 2);
}
return fibo_series[n];
}
int main ()
{
int n,res;
set_zero();
printf("Enter n : ");
scanf("%d",&n);
if(n>=100 || n<=0)
printf("Entered number is out of range!");
else
{
res=fibo(n-1);
printf("fibo(%d) = %d",n,res);
}
return 0;
}
Output:
输出 :
Enter n : 5
fibo(5) = 3
- This time firstly we initialize an array
fibo_series[]
with a maximum 100 elements to have a value 0, using the functionset_zero()
, 这次我们首先使用函数set_zero()
初始化一个数组fibo_series[]
,该数组最多包含100个元素,值为0 。 - This array is further going to be used to store the Fibonacci series’s elements as soon as one is calculated, 一旦计算出该数组,该数组将进一步用于存储斐波那契数列的元素,
- Inside the
fibo()
function first, we check whether the required element has been already calculated and stored inside the array or not. If not, it is calculated. And if yes, the element is directly passed to the site of the function call, 首先在fibo()
函数内部,我们检查所需的元素是否已经计算并存储在数组中。 如果不是 ,则进行计算。 如果是 ,则将元素直接传递到函数调用的位置, - This ensures that the same function(as we saw earlier fibo(3)) is not called twice. Hence in this way, we get the optimal solution. 这样可以确保同一函数(如我们先前看到的fibo(3)) 不会被调用两次。 因此,通过这种方式,我们获得了最佳解决方案。
Note: We pass (n-1)
while calculating res to the function fibo()
since the array index starts from zero. Whereas, we are considering the elements of the series to start with index 1.
注意:由于数组索引从零开始,因此在计算res时将(n-1)
传递给函数fibo()
。 鉴于我们正在考虑从索引1开始的系列元素。
For the same reason, we have used an if-else statement to eliminate the cases where the user enters n as n>=100
or n<=0
.
出于相同的原因,我们使用了if-else语句来消除用户以n>=100
或n<=0
输入n的情况。
结论 (Conclusion)
So in this tutorial, we learned about the Dynamic Programming technique with its implementation and how it gives us an optimal solution.
因此,在本教程中,我们学习了动态编程技术及其实现方法,以及它如何为我们提供最佳解决方案。
For any further questions, feel free to use the comments below.
如有其他疑问,请随时使用以下评论。
参考资料 (References)
- Data Structure and Algorithms, 数据结构和算法 ,
- Dynamic Programming – Wikipedia, 动态编程 –维基百科,
- What is the difference between bottom-up and top-down? – Stack Overflow Question. 自下而上和自上而下有什么区别? –堆栈溢出问题。
翻译自: https://www.journaldev.com/38299/what-is-dynamic-programming
动态编程语言静态编程语言