One Point Solution

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

Saturday, 8 December 2012

SRM 563: The trend has been stopped, for now

Posted on 13:18 by Unknown

So, to recap, I made the decision that from now on I will never solve a TopCoder division 1 easy problem in more than 10 minutes. This new strategy to open the hard and medium problems first and never open the easy until there are 10 minutes left is, of course, suicidal. It does not help that my rating was already trending downwards before making this decision.

Div1 hard

This problem seemed complicated. In fact, for a second I wondered if the match was going to be canceled because the problem is actually impossible.

I have not shared this but it has been decided that starting in SRM 564 I will always write the editorial, unless it is an exceptional case. Which means I now receive the editorial assignment and explanation of hard problem just half an hour after results are announced. In theory, this should make editorials arrive faster... in theory. What is important to know is that I now read the short explanation for this problem, and it turns out it was not difficult at all ...

Div1 Medium - The one with magic cards

5 minutes after opening the hard problem, I gave up and opened the medium problem. My first reaction was that it seemed approachable. And it was.

You got a list of cards from left to right. Each card has a level and a damage value. You can use a card with level L and damage D if and only if there are at least L-1 cards to its right. In case you use the card, you perform D damage and the card and the L-1 cards to its right get removed from the game. Another allowed step is to move the right-most card to the left-most place of the list of cards. What is the maximum total amount of damage you can make?

The first step is to alter the problem a bit. You actually have a circle of cards, placed in clockwise order. At every point, you can take any of the cards of level L, take the L-1 cards to its right and the card itself and perform D damage. These two variations are equivalent.

To solve the variation, consider another variation. In which you have the cards in a line. Once again, you can pick any card and remove it and the L-1 cards next to it. But this time it is not a circle (for now).

To solve this easier variation of the problem we use dynamic programming. The issue is that you can remove cards in any order and the order can alter the result dramatically. Thus the main thing to approach is how to decide their removals following a fixed order...

In fact, imagine that we decide to use the i-th card. This means that the level[i]-1 next cards to it have to be removed. But then after this decision, we decide to also use card i+1. We got to use card i+1 before using card i. When we decided to remove card i, we decided that we owe level[i]-1 cards. After deciding that we will use card i+1 before card i, we actually increase the amount of cards owed by (level[i+1]-1), so that then we can decide what to do with card i+2, and so and so, assuming an amount of owed cards.

A different case is what happens when we decide not to use card i+1, then we will remove this card when we remove the owed cards. This means we will need one less card. The number of owed cards decreases by 1.

That logic allows a dynamic programming solution. f(p, owed) finds the maximum damage you can make by using the cards with index greater than or equal to p, and you currently owe owed cards. Note that the base case is when p=n, then owed must be 0.

The next issue is what to do in the circular case. There are two clever work around to this. The first one is to try all n ways to rotate the vector of cards, and then just solve using the previous method.

The second method is to assume that there was an amount initOwed of cards that we will owe after processing the last card in the input. Then at the start of the simulation, when p=0 we already owe some cards (that we will assume we will define to owe later). The base case changes, the amount of owed cards at the end must be the same as the one that was planned in advance.

It is funny but I used both approaches at the same time. But of course, only one is necessary.

Here is the code anyways:

Div1 easy

It was worth 300 points. I opened it with 9:50ish minutes left, and I knew it was going to be difficult. For the first 5 minutes I implemented a solution that turned out to be wrong. I tried to use the remaining time to come up with a solution or a cheap trick that allowed the wrong solution to work. With no success.

Challenge phase/etc

Not much happened afterwards. I eventually passed system tests in div1 500. At least the trend towards the bottom of the ratings is not going on.

int n; 
vector<int> lvl, dmg;

int dp[MAX+1][MAX+1];

int rec(int p, int owed)
{
int & res = dp[p][owed];
if (res == -1) {
if (p == n) {
if (owed == 0) {
res = 0;
} else {
res = -INF;
}
} else {
res = -INF;
//use this?
if (owed + lvl[p] - 1 <= n) {
res = std::max(res, dmg[p] + rec(p+1, owed + lvl[p] - 1 ) );
}
//do not use this
res = std::max(res, rec(p+1, std::max(owed - 1, 0) ) );
}
}
return res;
}

int maxDamage(vector <int> level, vector <int> damage)
{
n = level.size();
lvl.resize(n);
dmg.resize(n);
int res = 0;
for (int start = 0; start < n; start++) {
for (int i=0; i < n; i++) {
int j;
if (i < start) {
j = (n - start) + i;
} else {
j = i - start;
}
lvl[i] = level[j];
dmg[i] = damage[j];
}

memset(dp, -1, sizeof(dp));
res = std::max(res, rec(0, 0) );
}
return res;
}

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)
      • SRM 565: Huge little differences
      • I wrote SRM 564 (Except div1 hard)
      • SRM 563: The trend has been stopped, for now
      • Topcoder SRM 562 editorial preview (div1 1000)
      • Topcoder SRM 560-562: You people have stood in my ...
    • ►  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