One Point Solution

  • Subscribe to our RSS feed.
  • Twitter
  • StumbleUpon
  • Reddit
  • Facebook
  • Digg

Wednesday, 29 May 2013

SRM 580, WallGameDiv2, editorial preview

Posted on 12:39 by Unknown

Here is a preview of 579's editorial. Begin with division 2 hard. The editorial page contains this explanation and once the rest of the editorial is finished it might contain an updated/fixed version. This page is just the preview.

I intended to write this one even since Saturday . But I had difficulty coming up with an explanation that doesn't just jump to "calculate the worst path, duh!".

WallGameDiv2

Link to the problem statement. There is a board with digits (as costs) in some cells and letter x in the remaining cells. In the first turn, Eel can build some walls (possibly none) between any two vertically-adjacent cells. In the second turn, Rabbit places a token in the top-left (0,0) cell, then Rabbit gets to move the cell down, left or right to any existent cell that does not contain a X, the cost to do the move is equal to the digit written in the cell. The game finishes when Rabbit takes the token to the bottom row. Eel cannot place the walls in such a way that it is not possible for Rabbit to find an exit. Rabbit wants to spend as little as possible and Eel wants Rabbit to spend as much as possible. Return the total cost Rabbit pays if both Rabbit and Eel play optimally.

Eel's control of the game

Let us play from Eel's perspective. Rabbit starts at top left cell and may be able to move to many cells in the top row until a blocked cell or the border of the board:

In an example with three reachable cells in the top row, the Rabbit can move to any of them and them move to the cell bellow it. Ad Eel we can place walls to vertically sperate cells from each other. With the help of walls we can actually force the Rabbit to move to a specific one of them:

With the help of walls we can assume that the Rabbit will have to move the token to the position in the second row that we wanted. There are once again three locations in the lower row that are reachable. One of the other location is blocked with an 'x'. The remaining locations (in red) are not valid, because if we made the Rabbit move there, the Rabbit would be unable to reach the bottom row (The paths from each of the squares in that area to the bottom row are blocked). Although we have many valid locations where we can force the Rabbit to move, we should place walls in a way that maximize the cost. We must leave at least one of them open for the Rabbit, though:

Then we face other three choices where to put the wall gap. The image to the right shows the whole path the Rabbit took to reach the bottom row.

The path the Rabbit takes at the end is a simple path, the Rabbit never visits the same square twice. There is no reason to, because the Rabbit already knows the positions of all the walls and can take a direct route. The simple path will finish at any of the cells in the bottom row.

Although the previous logic to consider sub-problems with the starting cell in each row in mind allows a dynamic programming solution. If you instead notice that Eel can force Rabbit to take any simple path to the bottom row that Eel prefers we can have a simpler one. For example, consider the following simple path:

It is possible to decide walls that force Rabbit to take any valid simple path we want. Eel wants Rabbit to spend the maximum cost possible. The path Eel forces Rabbit to take should be the one that has the largest possible sum of cell values, the worst simple path (It must be valid though, it must finish at one of the cells in the bottom row.).

Worst valid path from (0,0) to the bottom

A path is a sequence of cells. A simple path is a sequence of cells that does not visit the same cell twice. We can try a backtracking logic: The fist cell in the path is (0,0). When the current cell is (x,y), there are up to three choices for the next cell in the path:

  • (x,y+1) : Move down
  • (x - 1,y) : Move left.
  • (x + 1,y) : Move right.

In many cases some of these moves are invalid. The new cell could have a 'x' and be blocked. It is also possible that no valid path is possible if you move to that cell. Or maybe the cell does not exist (you are at one of the borders and can only move in one horizontal direction). Or maybe the cell was already visited by the path, which would not be good because the path must be simple. Because we can't move up, the only way to visit a cell that was already visited is to move backwards - Move left after a move to the right or vice versa. Thanks to this we only need to remember three variables: (x,y) the current cell and d, the previous direction. For example d is 1 if the previous move was to the left, 2 if the previous move was right and 0 otherwise. The result is a recurrence relation f(x,y,d) that returns the worst path starting at (x, y) such that the new direction is consistent with d:

  • f(x,h - 1,d) = (cost(x, h-1)) (If h is the height of the board, then all cells at row (h - 1) are in the bottom. The path has finished.
  • f(x, y, d) = -INF (A very small negative number) in case there are no valid paths starting at (x,y) such that the next direction is consistent with d. If (x, y) is "x" assume also that the result is -INF. We use -INF to mark this state as invalid, because the latter steps maximize the result, so any valid result will be greater than the invalid result.
  • f(x, y, 0) = cost(x, y) + (The worst path out of f(x, y+1, 0), f(x-1, y, 1), f(x+1, y, 2) ). (E.g: If we decide to move right, the new value of d is 2, and the next starting cell is (x+1, y).
  • f(x, y, 1) = cost(x, y) + (The worst path out of f(x, y+1, 0) or f(x-1, y, 1) ). (The previous move was to the left, it is not valid to move right).
  • f(x, y, 2) = cost(x, y) + (The worst path out of f(x, y+1, 0) or f(x+1, y, 2) ). (The previous move was to the right, it is not valid to move left).

This recurrence relation is a cyclic and has a limit number of state combinations O(w*h) (There are at most three values of d for each cell). We can use memoization to implement it in polynomial time.

vector<string> costs;
int w, h;
int dp[50][50][3];
int worstPath(int y, int x, int d)
{
const int INF = 1000000000;
int res = dp[y][x][d];
if (res == -1) {
int c = costs[y][x]-'0';
if ( costs[y][x] == 'x') {
// Invalid
res = -INF;
} else if (y == h-1) {
// Base case, the bottom is the end of the road:
res = c;
} else {
// Move down:
res = c + worstPath(y+1, x, 0);

// Move left (as long as the previous move was not right)
if ( (d != 2) && (x > 0) ) {
res = std::max(res, c + worstPath(y, x-1, 1) );
}
// Move right (as long as the previous move was not left)
if ( (d != 1) && (x < w-1) ) {
res = std::max(res, c + worstPath(y, x+1, 2) );
}
}
// memoize the result:
dp[y][x][d] = res;
}
return res;
}
int play(vector <string> costs)
{
//Save some variables for use by the worstPath function:
this->costs = costs;
w = costs[0].size();
h = costs.size();
// initialize the whole dp[][][] array with -1:
memset(dp, -1, sizeof(dp));
// Solution: x=0, y=0, d=0
return worstPath(0,0, 0);
}

Email ThisBlogThis!Share to XShare to Facebook
Posted in editorial, srm, topcoder | No comments
Newer Post Older Post Home

0 comments:

Post a Comment

Subscribe to: Post Comments (Atom)

Popular Posts

  • TopCoder SRM 557 - finally
    SRM 557 Explanation for division 1 Easy and match recap. Explanations for div2 easy and div2 medium. It feels like it has been ages since t...
  • SRM 589 Editorial
    I have finished writing the editorial for TopCoder SRM 589: http://apps.topcoder.com/wiki/display/tc/SRM+589 . As you most likely noticed. L...
  • SRM 590 recap and editorial
    Another week another Topcoder match. Not a great day. I had a bad flu and still do. Div1 500: The one with Xor Given a list of cards with nu...
  • SRM 546: relief
    I figured I should post something about this SRM. I've been very busy these weeks because the semester is ending and I tried to win a t-...
  • SRM 526: The killing wait for results
    While I wait for results, here is my perspective on this algorithm contest. It began with issues, it had to be postponed 15 minutes. TC has ...
  • SRM 554 div1 hard: TheBrickTowerHardDivOne
    Link to problem statement We got infinitely many bricks of dimensions 1x1x1 and C different colors. Count the number of towers of size 2x2...
  • SRM 533: Div1 500 MagicBoard explanation
    Finally solved it. It is a nice problem that is worth explaining in a post. You have a grid/board of at most 50x50 cells. Some cells contain...
  • Member SRM 505: Part 1
    So, let me explain a couple of problems from a Topcoder Member SRM that I wrote and never got an editorial. BTW, it was the last member SRM....
  • ListedLinks 2012-02-10
    Saturday Morning Breakfast Cereal comics: Grace Hopper's ghost That Oracle engineer blog post Oracle would really not like anyone to se...
  • Codeforces "Good bye 2013" round
    So it was a special round for coders of both divisions, problems ranged from the super easy problem A to the super difficult problems E,F,G....

Categories

  • acm
  • algorithm
  • answers
  • arenaplugin
  • badday
  • behindthescenes
  • bugs
  • c++
  • censorship
  • codechef
  • codeforces
  • contests
  • crocchamp
  • editorial
  • editorial.srm
  • embarrassing
  • explanation
  • gcj2013
  • gmp
  • goodday
  • google
  • googlecodejam
  • greed
  • groklaw
  • health
  • html
  • httpseverywhere
  • implementation
  • ipsc
  • ispc
  • java
  • kawigiedit
  • kindagoodday
  • lamebook
  • languages
  • lego
  • listedlinks
  • marathon
  • nasa
  • offtopic
  • ouch
  • postmortem
  • postportem
  • practical
  • probably_not_a_good_tip
  • problemsetting
  • programming
  • python
  • quora
  • rant
  • recap
  • slightlygoodday
  • snippet
  • srm
  • stl
  • strategy
  • swerc
  • tco
  • tco12
  • tco13
  • tco2012
  • tco2013
  • ternarysearch
  • topcoder
  • tricks
  • ubuntu
  • uva
  • vjass
  • vkcup
  • wc3
  • zinc

Blog Archive

  • ►  2014 (1)
    • ►  January (1)
  • ▼  2013 (141)
    • ►  December (14)
    • ►  November (8)
    • ►  October (13)
    • ►  September (11)
    • ►  August (14)
    • ►  July (15)
    • ►  June (13)
    • ▼  May (13)
      • Script to recover the old gmail favicon
      • SRM 580 Editorial now published
      • SRM 580 recap and WallGameDiv1 editorial preview
      • SRM 580, WallGameDiv2, editorial preview
      • SRM 579 Editorial preview: TravellingPurchasingMan...
      • SRM 579 Editorial preview: RockPaperScissors
      • Life with chronic headache
      • SRM 579 - Disaster averted?
      • Editorial for TCO round 2C hard: WellTimedSearch
      • TCO 2013 round 2C: bummer (And editorial for 250)
      • Regarding the smug opposition to programming contests
      • Editorial for SRM 577 div1 hard: BoardPainting
      • SRM 577 Editorial for div1 medium: EllysChessBoard
    • ►  April (12)
    • ►  March (11)
    • ►  February (11)
    • ►  January (6)
  • ►  2012 (94)
    • ►  December (5)
    • ►  October (6)
    • ►  September (8)
    • ►  August (6)
    • ►  July (3)
    • ►  June (5)
    • ►  May (8)
    • ►  April (10)
    • ►  March (20)
    • ►  February (16)
    • ►  January (7)
  • ►  2011 (51)
    • ►  December (7)
    • ►  November (12)
    • ►  October (5)
    • ►  September (1)
    • ►  August (3)
    • ►  July (4)
    • ►  June (3)
    • ►  May (7)
    • ►  April (3)
    • ►  March (2)
    • ►  February (1)
    • ►  January (3)
  • ►  2010 (9)
    • ►  December (4)
    • ►  October (1)
    • ►  June (1)
    • ►  May (1)
    • ►  January (2)
  • ►  2009 (1)
    • ►  December (1)
Powered by Blogger.

About Me

Unknown
View my complete profile