One Point Solution

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

Saturday, 17 December 2011

SRM 527: Slooow

Posted on 10:27 by Unknown
This was a very slow week, with no contests, I felt I was out of shape. Anyway, it seems I did sort of well.

Div1 450: P8XMatrixRecovery
You are given the rows of a binary matrix in correct order, some cells are ?, which means they can be 0 or 1. You are also given the columns, in the same format but this time not necessarily in the correct order. Basically, you can try any permutation of columns. It is guaranteed that there will be an answer, return the lexicographically-first matrix that follows the condition.

I noticed that the constraint on the dimensions was 30x30. It sort of led me to think that there was quite some freedom in the solution. When asked to build the lexicographically-first thing and the alphabet is reduced (there are only 0 or 1 as choices), it is possible to try cell by cell from top-left to bottom-right and try to find the lowest possible value in each position given the previous values found.

For example, in this case, imagine we knew of a function that took the rows and the columns and returned true if such matrix is possible. To build the lex-first matrix, just try each ? cell, and ask the question "Is it possible to have a matrix in which this position has 0 ? ". If the answer to that question is true, then the lex-first answer should have a 0 there, else it must have a 1 there. Make sure to use the newly-found values in subsequent iterations.

We just need to know how to answer that question. It is not so difficult. We have a set of columns and we want to assign a unique position from 0 to n-1 to each of the columns. Now, notice that some columns are compatible with some positions and some are not. We can imagine this as a bipartite graph between columns and positions. There is an edge connecting a column with a position if they are compatible. Then use bipartite matching to solve this. Which in turn shall use Max flow. If a perfect matching exists, there is a valid matrix This logic solves the problem, and you can verify that it needs O(n^5) time complexity in total. That is where the 30x30 constraint comes into place...


struct P8XMatrixRecovery 
{
//The network class is just a interface to solve max flow.

bool doMatch(const vector<string> & rows, const vector<string> & columns)
{
int r = rows.size();
int c = columns.size();

network G;
for (int i = 0; i < 2*c; i++) {
G.addVertex();
}
G.sink = G.addVertex();
G.source = G.addVertex();
for (int i=0; i<c; i++) {
G.addEdge(G.source, i, 1);
G.addEdge(i+c, G.sink, 1);
}

// Use bipartite matching between columns and positions.
for (int i=0; i<c; i++) { //O(n^3)
for (int j=0; j<c; j++) { //O(n^4)
// O(n^5)
bool can = true;
for (int k=0; (k<r) && can; k++) { //O(n^5)
char a = rows[k][j];
char b = columns[i][k];
if ( a != '?' ) {
if (b != '?') {
can &= (a == b);
}
}
}
if (can ) {
G.addEdge(i, j + c, 1);
}
}
}
int f = G.maxFlow();
return (f == c); //O(n^3)
}

vector <string> solve(vector <string> rows, vector <string> columns)
{
int r = rows.size();
int c = columns.size();
vector<string> res = rows;

// For each unknown cell.
for (int i=0; i<r; i++) {
for (int j=0; j<c; j++) { //O(n^2)
if (rows[i][j] == '?') {
//Is it possible to place 0 here?
res[i][j] = '0';
if (! doMatch(res, columns)) {
// If not, place a 1.
res[i][j] = '1';
}
}
}
}

return res;
}
};



Div1 275: P8XGraphBuilder
So, the problem scores would suggest that this problem was about as hard as the medium. I found it to be harder :). Well, you are given an array of N-1 elements: scores . You have to build a connected graph with N nodes and N-1 edges such that the sum (scores[degree of (vertex i) - 1]) for all i is as large as possible.

I was headed to the right answer from the beginning: A N vertices graph with N-1 edges that is connected is just a fancy way to say "Tree". Trees are quite compatible with dynamic programming, because you can consider each node a root of its own subgraph. In an undirected tree, You can also consider any node of the tree to be a root.

At first I had some issues giving a body to the solution. I eventually came to this: Imagine the state F(current_degree, available_children). You want to return the maximum score a single 'root' will have given its current_degree and the number of children available to add as children or grand-children to this root.

If available_children is 0, then we cannot do anything, the score is score[Current_degree - 1].

If available_children is not 0, then we are forced to add a new child to the 'root'. This is the recursive part. Let us name k the number of vertices that will be children for the new node. Then the total result will be the sum of F(current_degree+1, available_children - 1 - k) + F(1, k). Why? Ok, the degree of the "root" will increase by 1. The number of available children for the remaining nodes, decreases by 1+k. But the new child will also have a score of its own, its degree is initially 1, because of its connection to the root, and it has k nodes available for him.

We can iterate all the values of k, and select the one that maximizes the result.

struct P8XGraphBuilder 
{
int N;
vector<int> scores;
int mem[100][100];
int rec(int currentdeg, int avchildren)
{
int & res = mem[currentdeg][avchildren];
if (res == -1) {
res = 0;
if (avchildren == 0) {
if( currentdeg != 0) {
res = scores[currentdeg-1];
}
} else {
//how many grandchildren for the next child?
for (int k=0; k<avchildren; k++) {
res = std::max(res, rec(currentdeg+1, avchildren-1-k)
+ rec(1, k) );
}
}
}
return res;



}

int solve(vector <int> scores)
{
this->scores = scores;
int N = scores.size() + 1;
memset(mem,-1,sizeof(mem));
return rec(0, N-1);
}
};


Div1 1050
I think this problem is all about Lucas' theorem. Mostly because of the low modulo value and some other aspects. But I have no further idea.

---
It seems I did well, the only risks would be a silly typo in some code. My performance was slower than many other coders that solved both problems though.
Email ThisBlogThis!Share to XShare to Facebook
Posted in explanation, 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)
    • ►  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)
      • SRM 528: System tests delayed again
      • It's unnamed holiday day
      • The minifig problem
      • SRM 527: Slooow
      • No more link spam, for now
      • SRM 526: The killing wait for results
      • Codeforces round #96 (division 2)
    • ►  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