Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/131.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 高效的C/C++;二维最大和窗算法_C++_Algorithm_Sliding Window - Fatal编程技术网

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)
    (K+1)*K
    窗口),然后合并结果(a
    (K+1)*(K+1)
    无角正方形是两个矩形的并集,大小分别为
    K*(K+1)
    (K+1)*K

    if((ii=i)&&(jj=j))
    应该是
    if((ii==i)和&(jj==j))
    在您的可选游戏描述中,玩家对硬币的分配了解多少?什么都不知道,都在他们的K窗口内,或者完整的分配?总之,这看起来是一个很好的动态编程应用程序。如果还没有完成,我今晚会写一个答案。@Baiz,谢谢您的更正。这是indeed
    =
    ,我刚刚修复了它。@davidhigh,玩家们知道整个地图上的硬币分布情况。这个问题不是很明确,但这不是一个传统的滑动窗口问题,因为这些值在离线时并不都可用。我已经再次阅读了这个问题,但我仍然找不到它说这些值不可用的地方脱机可用。@davidesenstat所有值
    c[i][j]
    都可用。我也对原始帖子发表了评论。@Adama Of
    c
    ,但不是
    opt
    ,这就是您滑动窗口的原因。@davidesenstat是的,那是正确的。您没有以前的值;要计算
    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