如何使用动态编程(DP)转换以下递归程序? 我尝试将此代码重新定义为动态编程形式时遇到了一些麻烦。我得到了基本案例并确定了一般情况,我知道DP是关于自下而上的"方法
int add(int, int);
int main()
{
int x = 0, y = 0;
printf("Enter positive integers x, y: ");
scanf("%d %d", &x, &y);
printf("Result: %d\n", add(x, y));
return 0;
}
int add(int x, int y)
{
if(x < 0 || y < 0){
fprintf(stderr, "Negative Integer received!\n");
return -1;
}
if (x == 1 || y == 1)
return 1;
else
return add(x, y-1) + add(x - 1, y) + add(x-1, y-1);
}
答案 0 :(得分:1)
您的代码将导致所有可能的x,y和z整数(负,正)组合的堆栈溢出
答案 1 :(得分:1)
为什么要以递归方式执行此操作?有一种迭代的方式,迭代'几乎总是'胜过递归。除此之外,代码更少:
int DP[500][500];
memset(DP, 0, sizeof(DP));
for(int i=1; i<=x; i++) DP[i][1] = 1;
for(int i=1; i<=y; i++) DP[1][i] = 1;
for(int i=2; i<=x; i++) {
for(int j=2; j<=y; j++) {
DP[i][j] = DP[i-1][j-1] + DP[i-1][j] + DP[i][j-1];
}
}
printf("Result: %d\n", DP[x][y]);
但是如果你坚持递归,你可以通过指针传递你的DP数组。并且每次检查你之前是否计算过DP [i] [j],如果是这样的话不再计算并返回:
#include <stdio.h>
#include <string.h>
void add(int x, int y, int (*M)[500])
{
if(M[x][y] > 0) return;
if (x == 1 || y == 1) {
M[x][y] = 1;
return;
}
add(x, y-1, M);
add(x - 1, y, M);
add(x-1, y-1, M);
M[x][y] = M[x][y-1] + M[x-1][y] + M[x-1][y-1];
return;
}
int main()
{
int x, y;
printf("Enter x, y: ");
scanf("%d %d", &x, &y);
int DP[500][500];
memset(DP, 0, sizeof(DP));
add(x, y, DP);
printf("Result: %d\n", DP[x][y]);
return 0;
}