C++ 高效的C/C++;二维最大和窗算法
我有一个C++ 高效的C/C++;二维最大和窗算法,c++,algorithm,sliding-window,C++,Algorithm,Sliding Window,我有一个c[N][M]矩阵,我在(K+1)²窗口上应用最大和运算。我正试图降低朴素算法的复杂性 特别是,下面是我的C++代码片段: <!-- language: cpp --> int N,M,K; std::cin >> N >> M >> K; std::pair< unsigned , unsigned > opt[N][M]; unsigned c[N][M]; // Read values for c[i][j] //
c[N][M]
矩阵,我在(K+1)²
窗口上应用最大和运算。我正试图降低朴素算法的复杂性
特别是,下面是我的C++代码片段:
<!-- language: cpp -->
int N,M,K;
std::cin >> N >> M >> K;
std::pair< unsigned , unsigned > opt[N][M];
unsigned c[N][M];
// Read values for c[i][j]
// Initialize all opt[i][j] at (0,0).
for ( int i = 0; i < N; i ++ ) {
for ( int j = 0; j < M ; j ++ ) {
unsigned max = 0;
int posX = i, posY = j;
for ( int ii = i; (ii >= i - K) && (ii >= 0); ii -- ) {
for ( int jj = j; (jj >= j - K) && (jj >= 0); jj -- ) {
// Ignore the (i,j) position
if (( ii == i ) && ( jj == j )) {
continue;
}
if ( opt[ii][jj].second > max ) {
max = opt[ii][jj].second;
posX = ii;
posY = jj;
}
}
}
opt[i][j].first = opt[posX][posY].second;
opt[i][j].second = c[i][j] + opt[posX][posY].first;
}
}
。。。结果应该是opt[N-1][M-1]={14,11}
但是,此代码段的运行复杂性为O(N M K²)。我的目标是减少运行时的复杂性。我已经看到过类似于的帖子,但是我的“过滤器”似乎是不可分离的,可能是因为求和运算
更多信息(可选):这本质上是一种在“游戏”中开发最佳策略的算法,其中:
- 两名玩家在
地牢中带领一支队伍N×M
- 地牢的每个位置都有
金币c[i][j]
- 起始位置:
其中(N-1,M-1)
c[N-1][M-1]=0
- 活动玩家从位置
选择下一个移动团队的位置(x,y)
- 下一个位置可以是
。(x-i,y-j),i这里是
解决方案O(N*M)
- 让我们修复下一行(
)。如果每个列都知道r
和r-K
之间所有行的最大值,则此问题可以简化为众所周知的滑动窗口最大值问题。因此,可以在r
时间内计算固定行的答案O(M)
- 让我们以递增的顺序遍历所有行。对于每一列,
总时间复杂度为
和r-K
之间所有行的最大值也是滑动窗口最大值问题。处理每一列需要所有行的r
时间O(N)
。O(N*M)
但是,此解决方案有一个问题:它不排除
元素。通过运行上述算法两次(使用(i,j)
和K*(K+1)
窗口),然后合并结果(a(K+1)*K
无角正方形是两个矩形的并集,大小分别为(K+1)*(K+1)
(K+1)*KK*(K+1)
应该是if((ii=i)&&(jj=j))
在您的可选游戏描述中,玩家对硬币的分配了解多少?什么都不知道,都在他们的K窗口内,或者完整的分配?总之,这看起来是一个很好的动态编程应用程序。如果还没有完成,我今晚会写一个答案。@Baiz,谢谢您的更正。这是indeedif((ii==i)和&(jj==j))
,我刚刚修复了它。@davidhigh,玩家们知道整个地图上的硬币分布情况。这个问题不是很明确,但这不是一个传统的滑动窗口问题,因为这些值在离线时并不都可用。我已经再次阅读了这个问题,但我仍然找不到它说这些值不可用的地方脱机可用。@davidesenstat所有值=
都可用。我也对原始帖子发表了评论。@Adama Ofc[i][j]
,但不是c
,这就是您滑动窗口的原因。@davidesenstat是的,那是正确的。您没有以前的值;要计算opt
您必须了解所有opt[x][y]
,opt[x-i][y-j]
0底部。
c[N][M] = 4 1 1 2 6 1 1 1 1 2 5 8 1 1 8 0
- 让我们修复下一行(