【发布时间】:2020-03-18 12:27:20
【问题描述】:
我正在查看一个函数,需要将其转换为动态编程形式。但是我很难理解这个函数中使用的逻辑(基本情况是什么?),这个函数的原作者不再可以提问,我不能对他的工作做出正面或反面,而且有0 个可用文档。
说明:
此函数接受一个正整数矩阵,并通过以下方式找到最大和 从矩阵的每一列中选择一个元素,从左到右移动。当你穿过 矩阵逐列,总和会受到惩罚,具体取决于您的方式 相对于您之前的两个位置移动。如果您选择的下一行在前两行之间 选定的行,没有惩罚;但是,对于上面的每一行,您的总和将被罚款 2 前两个中的最大值或低于前两个中的最小值。
int calSum(int row, int cols, vector<vector<int>> inputArray, vector<int> *outputArray){
int ans[row][cols][row];
int index[row][cols][row];
int firstCol[row];
for(int i=0;i<row;i++){
firstCol[i]= inputArray[i][0] - 2*(i);
}
for(int i=0;i<row;i++){
for(int j=0;j<row;j++){
int penalty;
if(i<=j){
penalty=0;
}else{
penalty= 2* (i-j);
}
ans[i][1][j]= inputArray[i][1] - penalty+ firstCol[j];
}
}
for(int j=2;j<cols;j++){
for(int i=0;i<row;i++){
int nextRow= i;
for(int k=0;k<row;k++){
int currRow= k;
int ind=-1;
int maxVal= INT_MIN;
for(int l=0;l<row;l++){
int prevRow=l;
int max1= max(prevRow, currRow);
int min1= min(prevRow, currRow);
int penalty;
if(nextRow<=max1&&nextRow>= min1){
penalty=0;
}else if(nextRow>max1){
penalty= 2*(nextRow-max1);
}else{
penalty= 2*(min1-nextRow);
}
int val= -penalty+ inputArray[i][j] + ans[k][j-1][l];
if(val>maxVal){
maxVal=val;
ind=l;
}
}
ans[i][j][k]=maxVal;
index[i][j][k]=ind;
}
}
}
int max=INT_MIN;
int x=-1;
int y=-1;
for(int i=0;i<row;i++){
for(int j=0;j<row;j++){
if(ans[i][cols-1][j]>max){
max= ans[i][cols-1][j];
x=i;
y=i;
}
}
}
for(int j=cols-1;j>=2;j--) {
outputArray->push_back(x);
int temp=x;
x= y;
y= index[temp][j][y];
}
outputArray->push_back(x);
outputArray->push_back(y);
return max;
}
我已经尝试过跟踪代码并一直迷失在逻辑中。非常感谢您对此函数所做的基本解释。
【问题讨论】:
-
问题是什么?您需要解释此功能的工作原理吗?什么是“动态表单”?
-
请注意,variable-length arrays(例如
ans和index)不在 C++ 中。请改用std::vector。 -
@Someprogrammerdude 这是我在查看代码时非常困扰的事情。我知道 C++ 不支持 VLA,但作者以某种方式在这里使用了它们 - 我选择暂时忽略它,因为我对代码本身没有问题,我更关心弄清楚这个函数中使用的逻辑.
-
一些编译器(咳 GCC 咳)把它作为一个不可移植的扩展。这就是为什么我总是尽可能地禁用扩展。
-
问题陈述不完整:前两列有惩罚吗?
标签: c++ algorithm recursion optimization dynamic-programming