Algorithm 在棋盘上找到所有可能的方块,不包括选定的单元格

Algorithm 在棋盘上找到所有可能的方块,不包括选定的单元格,algorithm,dynamic-programming,combinatorics,Algorithm,Dynamic Programming,Combinatorics,我有一个小小的变化,在棋盘上找到所有的方块 我知道我们可以从8x8大小的棋盘上找到所有可能的方块 前8个数的平方和 1^2 + 2^2 + 3^2 + 4^2 ... 8^2 但是如果有一些格子被棋子占据,我们需要排除所有包含这些棋子的方块 例如在4x4矩阵以下考虑 。x x 总平方=30-{1(4x4)+4(3x3)+6(2x2)+2(1x1)}=30-13=17 我想用DP来解决这个问题,但无法准确识别如何排除被禁止的方块 提前谢谢 您可以在N^3中解决它。对于每个单元格(x,y),您

我有一个小小的变化,在棋盘上找到所有的方块

我知道我们可以从8x8大小的棋盘上找到所有可能的方块 前8个数的平方和 1^2 + 2^2 + 3^2 + 4^2 ... 8^2

但是如果有一些格子被棋子占据,我们需要排除所有包含这些棋子的方块

例如在4x4矩阵

以下考虑

。x x

总平方=30-{1(4x4)+4(3x3)+6(2x2)+2(1x1)}=30-13=17

我想用DP来解决这个问题,但无法准确识别如何排除被禁止的方块


提前谢谢

您可以在N^3中解决它。对于每个单元格(x,y),您需要一个函数来告诉是否存在高度=z,z从0到n,以及(右,下)=(x,y)的空正方形

现在的问题是如何创建这个函数

你可以用部分和来做。对于每个单元格(x,y),保存DP[x][y]=矩形(0,0)、(x,y)中的棋子数。然后你可以回答O(1)中的函数

有用链接:

编辑#1(n^2logn):
我认为,通过在上面讨论的函数中对平方高度进行二进制搜索,可以压缩一点性能(N^2*log(N))。这是因为如果z=10(意味着你可以在(x,y)中放置一个高度为10的正方形),那么很明显你也可以放置一个z=9,8,7…1的正方形

编辑#2(n^2):
是的,你是对的,你可以在n^2:)中完成。考虑上面的函数,问题是:如果我知道(x-1,y)、(x,y-1)和(x-1,y-1)的响应,电流(x,y)的最大z(高度)是多少?所以这里的想法是:当前位置的最大z=z从(x-1,y),(x,y-1),(x-1,y-1)+1的最小值


我认为这种方法是有效的,但我一直在寻找n^2的范围。有没有可能用n^2来计算呢?好的,最后得出了n^2的解。该死,我已经有一段时间没做algo了;)@VarunNarisetty算法对你有用吗?如果你需要帮助,请告诉我谢谢你的更新。看起来这个解决方案有效。让我来实现这一点,并给你一个更新。
int n,m,dp[100][100],rs;
char a[100][100];

int main() {

    std::cin >> n >> m;
    for (int i=1; i<=n; i++) {
        for (int j=1; j<=m; j++) {
            std::cin >> a[i][j];
        }
    }

    for (int i=1; i<=n; i++) {
        for (int j=1; j<=m; j++) {
            if (a[i][j] == 'x') continue;
            rs += dp[i][j] = min(dp[i-1][j], min(dp[i][j-1], dp[i-1][j-1])) + 1;
        }
    }

    std::cout << rs << std::endl;

    for (int i=1; i<=n; i++) {
        for (int j=1; j<=m; j++) std::cout << dp[i][j] << ' ';
        std::cout << endl;
    }

    return 0;
}
4 4
....
....
.xx.
....
17
1 1 1 1
1 2 2 2
1 0 0 1
1 1 1 1