One Point Solution

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

Sunday, 2 September 2012

SRM 554

Posted on 19:09 by Unknown

I posted something about SRM 554 TCO blog. Extra comments:

I had quite a silly luck this time. I do not why, but I took very long in the 250 points one. Probably because I went from the general case to the specific case instead of the opposite. So I was just about to solve the problem finding the union of three arithmetic sequences, until I started doing an extra analysis to notice that many of the intersections are not possible.

Pretty code for that problem:

int find(int redCount, int redHeight, int blueCount, int blueHeight) 
{
return
+ min(redCount, blueCount)
+ 1 + min(redCount-1, blueCount)
+ 1 + min(redCount, blueCount-1)
- (redHeight == blueHeight) * (min(redCount, blueCount) );
}

For div1 500, I messed up even more spectacularly. I reached the conclusion of the condition that was necessary to reach the optimal result (but I did not think to prove that it is also sufficient, knowing that it was also sufficient would have saved me a lot of problems). The problem is that after that, I used a dynamic programming approach. I took some time to code it, until I found that I was failing the last example (Which does not make sense, because the condition IS necessary). I did a quick fix by adding a dimension to the dp. The quick fix was not necessary, but it passed the examples so I submitted the problem.

Then I noticed that I had too many dimensions and my approach could be too slow (It was n6 in theory, but maybe it runs faster). I tried some random test cases, until I found one that was not timing out, but instead breaking an assertion I added while debugging the first bug. It turns out that I was sorting an array after I make the copy that was in use by the dynamic programing algorithm. So, I fixed that bug, which fixed the assertion, but now, as I suspected, was timing out. I figured that maybe that lame bug was the one that caused my initial solution to fail. There was only 1 minute left. Somehow, I managed to get rid of the extra dimension in the dp, pass examples and re-submit before the end of the coding phase.

Challenge phase was more about feeling very nervous. I felt the approach was right, but overcomplicated , so there was plenty of room for failure. At the end I passed. (yay)

Here is pretty code for it:

vector<int> find(vector<int> heights) 
{
int n = heights.size();
vector<int> res(n, 0), used(n, false);
used[0] = true;
//res[0] = 0 is always possible.
// Yes, it is always possible to choose any arbitrary first element and still
// follow the condition (non-increasing and then non-decreasing)
//
for (int i=1; i<n; i++) {
for (int j=n-1; j>=0; j--) {
if (! used[j]) {
if (heights[j] <= heights[ res[i-1] ] ) {
//this is always fine.
// If an element j exists such that:
// heights[j] < heights[res[i-1])
//
// It means that the next case was never reached. Thus it is
// still possible to do it.
//
// if heights[j] = heights[res[i-1]], then it can count as
// either of the cases and also fine.
res[i] = j;
} else {
// If the new element is greater, then it must forcefully be
// equal to the minimum of the remaining elements so that the
// rest of the elements are placed in non-decreasing order.
bool can = true;
for (int k=0; k<n; k++) {
can &= (used[k] || (heights[k] >= heights[j]) );
}
if (can) {
res[i] = j;
}
}
}
}
used[res[i]] = true;
}
return res;
}

As you can see, Figuring out (and proving) that the condition is not only necessary but also sufficient allows a VERY simple approach.

Div2 1000 was cute. Here is code for it too:

const int MOD = 1234567891; 
#define for_each(q, s) for(typeof(s.begin()) q=s.begin(); q!=s.end(); q++)
struct TheBrickTowerHardDivTwo
{
int pow5[5];
int mem[8][48][5*5*5*5];

// I encode each state as a single number in base 5.
// (I added a fifth color that is a wildcard. So that the top-most row
// in a dp can add any colors without decreasing K).
//
// The transition array saves all the possible transitions from a state
// of colors to another AND the value we have to decrease from K.
// It is sorted non-decreasingly by the value to decrease from K, so that
// we can stop when K would get less than 0.
vector<pair<int,int> > transition[5*5*5*5];


int rec(int K, int H, int state)
{
int &res = mem[K][H][state];
if (res == -1) {
if (H==0) {
res = 1; //empty
} else {
long long tem = 0;
// Iterate through the list of transitions, try the transition
for_each(q, transition[state]) {
int nk = K - q->first;
if (nk >= 0) {
tem += rec(nk, H-1, q->second);
} else {
break;
}
}
res = (int)( tem % MOD);
}
}
return res;
}

int find(int C, int K, int H)
{
pow5[0] = 1;
for (int i=1; i<=4; i++) {
pow5[i] = 5*pow5[i-1];
}
memset(mem, -1, sizeof(mem));

// make the transitions
for (int state=0; state<pow5[4]; state++) {
for (int newstate=0; newstate < pow5[4]; newstate++) {
bool valid = true;
int krem = 0;
for (int i=0; i<4; i++) {
int x = (newstate / pow5[i])%5;
// use only C colors...
valid &= ( x < C);
// sharing face with the above brick
if ( (state/pow5[i]) % 5 == x) {
krem++;
}
// We represent the colors in this way.
// [0][1]
// [3][2]
// This means that a cube is adjacent to the next and previouis
// index. Which translates to us needing to check index (i+1)%4
int y = (newstate / pow5[ (i+1) % 4 ]) % 5;
if (y == x) {
krem ++;
}
}
if (valid && (krem <= K) ) {
transition[state].push_back( make_pair(krem, newstate) );
}
}
sort(transition[state].begin(), transition[state].end());
}
long long res = 0;
for (int i=1; i<=H; i++) {
res += rec(K, i, pow5[4] - 1 );
}
return (int)(res % MOD);
}
};

Email ThisBlogThis!Share to XShare to Facebook
Posted in algorithm, 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)
      • Surprise test SRM the 25-th (Tomorrow!)
      • Codeforces #140 (Div 1)
      • Learning to find bugs
      • SRM 556 : #@!$%!
      • SRM 554 div1 hard: TheBrickTowerHardDivOne
      • Codeforces #137 (div2) C. Reducing Fractions - update
      • SRM 555: 5555555555555555555555
      • SRM 554
    • ►  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