如何将这个递归转化为迭代DP
How do I convert this recursion into iterative DP?
我想解决这个问题:TRT。以下是我到目前为止所做的:我为给定的问题设计了一个递归,并使用记忆法使解决方案被接受。
int recur(int l,int r,int level)
{
if(l==r)
return level*a[l];
if(dp[l][r])
return dp[l][r];
return dp[l][r]=max(level*a[l]+recur(l+1,r,level+1),level*a[r]+recur(l,r-1,level+1));
}
我正试图通过自下而上的动态规划来解决这个问题,但我想不出这个方法,这种情况发生在我正在解决的大多数动态规划问题上,我能够设计递归,但在构建迭代dp时失败。有谁能在我弄清楚递归后告诉我迭代dp解的方法吗?
编辑:基于Tempux的解释,我自下而上的DP解决方案:
int solve()
{
REP(i,n)
{
dp[i][i]=n*a[i];
}
REPP(i,1,n)
{
for(int j=0;j+i<n;j++)
{
dp[j][j+i]=max((n-i)*a[j]+dp[j+1][j+i],(n-i)*a[j+i]+dp[j][j+i-1]);
}
}
return dp[0][n-1];
}
一般来说,您只需要首先填充独立的值(基本情况)。然后填写依赖于您之前填写的值的值。
在这种情况下,当l==r你有一个独立的值。所以你先填满这些:[0][0][1][1][2][2]……(n - 1) (n - 1) 。
现在你可以看到,价值 [l] [r] 取决于 [l + 1] [r] 和 [l] (r1) 。现在你可以填充[0][1][1][2][2][3]的值…[n] (n - 1) 。
[0][1] is dependent on [0][0] and [1][1] which you have filled before
[1][2] is dependent on [1][1] and [2][2] which you have filled before
....
现在你认识到一个模式了。如果按对角线操作,可以填满整个表。
0 * * * * 0 1 * * * 0 1 2 * * 0 1 2 3 *
* 0 * * * * 0 1 * * * 0 1 2 * * 0 1 2 3
* * 0 * * * * 0 1 * * * 0 1 2 * * 0 1 2
* * * 0 * * * * 0 1 * * * 0 1 * * * 0 1
* * * * 0 * * * * 0 * * * * 0 * * * * 0
这是一个可能的实现:
for ( int d=0; d<=n-1; ++d ){
for ( int l=0; l<=n-1; ++l ){
int r = l+d;
if ( r >= n )
break;
int level = n-(r-l);
if ( l==r ){
dp[l][r] = level*v[l];
} else {
dp[l][r] = max( level*v[l] + dp[l+1][r],
level*v[r] + dp[l][r-1] );
}
}
}
相关文章:
- 使用std::multimap迭代器创建std::list
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- C++中带有List类的迭代器Segfault
- 迭代时从向量和内存中删除对象
- 如何在c++迭代器类型中包装std::chrono
- 带过滤器的现代迭代c++集合
- 在c++中检查长方体是否尽可能快地重叠(无迭代)
- C++矢量迭代
- 集合上的输出迭代器:assign和increment迭代器
- Boost Spirit,获取迭代器内部语义动作
- 擦除while循环中迭代的元素
- 实现一个在集合上迭代的模板函数
- 对于set上的循环-获取next元素迭代器
- 在向量内的向量上迭代
- 为什么output_editor Concept不需要output_e迭代器标记
- TSP递归解的迭代形式
- c++17文件系统::recursive_directory迭代器()在mac上没有给出这样的目录,但在windows上
- 使用迭代器时如何访问对象在向量中的位置?
- 将此代码从递归 DP 转换为迭代 DP
- 如何将这个递归转化为迭代DP