Anthony_Smith's blog

By Anthony_Smith, history, 2 years ago, In English

The well-known Parquet Problem asks the following: Given an N x M board, find the number of ways to tile it using only 1 x 2 or 2 x 1 tiles. We can solve this with various DP formulations that result in various time complexities, but one thing all these methods have in common is the use of the "DP on Broken Profile" method — that is, using a bitmask to represent the state of a certain set of cells (usually a row or column).

My question is: Can someone fully explain the DP state for the $$$O(2^NNM)$$$ DP-on-Broken-Profile approach to this problem, including how the base cases fit conceptually with the overall process? (As for the transitions, I'm (possibly wrongly) assuming that once I fully understand the DP-state, the transitions will be trivial)

The only explanation I could find for this approach comes from USACO Guide. However, the explanation is confusing and seems to include

My understanding of their DP-state is that $$$dp[i][j][mask]$$$ = the number of ways to tile the grid so that basically columns 0 to $$$j - 2$$$ are all completely filled. Meanwhile, column $$$j - 1$$$ may not be completely filled, but must be filled from rows 0 to $$$i$$$. And $$$mask$$$ represents whether or not rows 0 to $$$i$$$ in column $$$j$$$, and rows $$$i + 1$$$ to $$$N - 1$$$ in column $$$j - 1$$$, are filled. Below is their explanation:

This explanation fits with the picture. But, when I actually run their provided program, I get DP-values that don't seem to agree with my understanding. Mainly, I don't understand what the DP-state means conceptually when $$$j = 0$$$. For instance, one value we get is that $$$dp[1][0][0011] = 1$$$. Based on my understanding, this basically represents the number of ways to tile only the leftmost-column, and only the bottommost two cells, so $$$1$$$ does make sense here.

But $$$dp[1][0][1100] = 0$$$! Shouldn't this just equal $$$1$$$ as well, since it represents the number of ways to tile only the top two squares of the leftmost column??

  • Vote: I like it
  • +15
  • Vote: I do not like it

»
2 years ago, # |
  Vote: I like it 0 Vote: I do not like it

Glad that I am not the only one having a really hard time understanding DP on broken profile. This problem has been bugging me for more than an year now. Hope someone explains. Bump.

»
2 years ago, # |
  Vote: I like it 0 Vote: I do not like it

"dp[1][0][0011]=1. Based on my understanding, this represents the number of ways to tile only the leftmost-column, and only the bottommost two cells, so 1 does make sense here.

But dp[1][0][1100]=0! Shouldn't this just equal 1 as well, since it represents the number of ways to tile only the top two squares of the leftmost column??"

Why it doesn't make sense? dp[1][0][0011] = 1:

  • You are at column 0, row 1.

  • 0011

    1. bit 0 and bit 1 equal 0, which means a[0][0] and a[0][1] is not empty --> they are filled with a vertical 1x2 tile
    2. bit 2 and bit 3 equal 1, which means a[2][-1] and a[3][-1] is empty, that's true because the column -1 is outside of the board
  • 1100 is basically flip the mask so one value must be 0 and the other must be 1.

so the problem is: the mask in the DP state of the USACO Guide means: whether or not the cells are empty but you misunderstood the mask as: whether or not the cells are filled

hope this helps

»
2 years ago, # |
Rev. 9   Vote: I like it +4 Vote: I do not like it

USACO denotes mask as the mask of columns, but I'd rather use it as a mask of rows because I think it's easier to imagine.

denote $$$dp[i][j][mask]$$$ as the number of ways to get the state of:

  1. $$$((0, 0)$$$ to $$$(i-1, j))$$$ and $$$((i-2, j+1)$$$ to $$$(0, m-1))$$$ are filled.

  2. $$$((i, 0)$$$ to $$$(i, j))$$$ + $$$((i-1, j+1)$$$ to $$$(i-1, m-1))$$$ is denoted by mask of size m.

  3. and the rest of the cells are empty.

example on what does dp[2][2][1001101] denote:

notes:

  • if $$$j'th$$$ bit of mask is 0. it means it's empty, otherwise, it means it's filled.
  • if $$$j'th$$$ bit of mask is 0, it means we left it empty for now, and we need to fill it with a vertical tile from below or with a horizontal tile from right later.

Now we get some transitions that solves the problem using the states above:

if $$$j'th$$$ bit of mask is 1 while we're at $$$(i, j)$$$ and want to consider the case where we put a vertical tile on $$$((i-1, j), (i, j))$$$:

  • $$$dp[i][j][mask]+= dp[i][j-1][mask\bigoplus 2^{j}]$$$

if $$$j'th$$$ bit of mask is 1 while we're at $$$(i, j)$$$ and $$$j-1'th$$$ bit is also 1 and we want to consider the case where we will put horizontal tile on $$$((i, j-1), (i, j))$$$:

  • $$$dp[i][j][mask]+= dp[i][j-1][mask\bigoplus 2^{j-1}]$$$ (we are keeping $$$j'th$$$ bit open because it denote cell $$$(i-1, j)$$$ which has to be already filled when we put horizontal tile at $$$(i, j)$$$. otherwise, we wouldn't ever be able to fill it back.)

if $$$j'th$$$ bit is 0 while we're at $$$(i, j)$$$ and we want to consider the case where we leave it empty:

  • $$$dp[i][j][mask]+= dp[i][j-1][mask\bigoplus 2^{j}]$$$ (same case as previous one, we have to keep cell $$$(i-1, j)$$$ closed because otherwise, we wouldn't be able to close it later.)

base cases:

$$$j = 0:$$$

if $$$j'th$$$ bit of the mask is 0 and we consider leaving it empty:

  • $$$dp[i][0][mask]+= dp[i-1][m-1][mask\bigoplus 2^{j}]$$$

if $$$j'th$$$ bit of the mask is 1 and we consider placing vertical a tile:

  • $$$dp[i][0][mask]+= dp[i-1][m-1][mask\bigoplus 2^{j}]$$$

$$$i = 0:$$$

  • just assume $$$dp[-1][m-1][111...1] = 1$$$
  • »
    »
    2 years ago, # ^ |
    Rev. 3   Vote: I like it +6 Vote: I do not like it

    You say: Denote $$$dp[i][j][mask]$$$ as the number of ways to get the state of:

    $$$((0,0)$$$ to $$$(i−1,j))$$$ and $$$((i−2,j+1)$$$ to $$$(n−1,m−1))$$$ are filled.

    Shouldn't the second part be

    $$$((0, j + 1)$$$ to $$$(i - 2, m - 1))$$$? I thought that it would essentially represent every cell to the right of column $$$j$$$, and above row $$$i - 1$$$.