Saturday, February 16, 2013

Another DP problem

AvoidRoads

Another fun albeit a more straightforward problem. This one could be solved quite in a straightforward fashion by assuming the recurrence that for the given vertex, a path can only be drawn from two vertices one to the left and one below it. And the sum of both paths to this vertex is the total number of paths to this vertex.
A pictorial representation of my breakdown:
In the above diagram, the red point is the final destination.
 The pink points are the subproblems for the the red one, the paths from where we can reach the red one. For the Pink vertex to the left(x-1,y), I have shown two green points as the subproblems, and for the other pink one(x,y-1), I have shown a brownish color for the subproblems. Because of an overlap, one of the green and brown vertices have been drawn smaller than the others. 

Here is my method as code:


public long numWays( int maxX, int maxY, String[] bad) {
this.maxX = maxX;
this.maxY = maxY;
processBads(bad);
pathArr = new long[maxX +1 ][maxY + 1];
for(int i = 0; i <= maxX; i++)
for(int j = 0; j <= maxY; j++)
pathArr[i][j] = -1;
return pathsRec(maxX, maxY);
}


public long pathsRec(int x, int y) {
if(x <0 || y < 0)
return 0;
if( pathArr[x][y] != -1)
return pathArr[x][y];
if(x > maxX || x < 0 || y > maxY || y < 0)
return 0;
if(x == 0 && y == 0)
return 0;
if(x == 0 && y == 1 && valid(0,0,0,1))
return 1;
if(x == 1 && y == 0 && valid(0,0,1,0))
return 1;
long path1 = 0, path2 = 0;
if( valid(x, y, x-1, y) )
path1 = pathsRec(x -1, y);
if( valid(x, y, x, y-1) )
path2 = pathsRec(x, y-1);
pathArr[x][y] = path1 + path2;
return  (path1 + path2);

}


public boolean valid(int x, int y, int x1, int y1) {
if(x > maxX || x < 0 || y > maxY || y < 0)
return false;
for(int i =0; i< blocked.length; i++) {
boolean cond1 = x == blocked[i][0] && y == blocked[i][1] && x1 == blocked[i][2] && y1 == blocked[i][3];
boolean cond2 = x1 == blocked[i][0] && y1 == blocked[i][1] && x == blocked[i][2] && y == blocked[i][3];
if(cond1 || cond2 ) {
return false;
}
}
return true;
}


public void processBads(String[] bad) {
blocked  = new int[bad.length][4];
for(int i = 0; i < bad.length; i++) {
String[] temp = bad[i].split(" ");
blocked[i][0] = Integer.parseInt(temp[0]);
blocked[i][1] = Integer.parseInt(temp[1]);
blocked[i][2] = Integer.parseInt(temp[2]);
blocked[i][3] = Integer.parseInt(temp[3]);
}

}

No comments: