One Point Solution

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

Thursday, 10 May 2012

Codeforces round #119

Posted on 11:31 by Unknown

I am not excessively sure about my problems B and C. They seemed very correct when I coded them though. I just passed A. Let us see if results for my B and C come before I finish explaining A.

Div1 A / Div2 C

linky

So, constraints are large. So, let us try to think of a linear algorithm.

No matter what we do, our only allowed move is to remove last element and place it somewhere else. In fact, the only decision to make is the number of times we will repeat this step.

Let us focus on the number of times we do the step. So, for the first example:


3 2 1
1 2 3

And we repeat the step twice, then we will remove the first two numbers (2 1) and after that, we can just assume we put the two numbers in the best places imaginable. In this, case, (1 2) 3.

The other two examples:


1 2 3 4 5
1 5 2 3 4

1 5 2 3 4
1 2 3 4 5

In the first of them, we remove 5 and only five, after that, we can find a good spot for 5 and we will be ready. In the other case, we remove (2 3 4) , and it is enough.

Let us focus on why is it enough to do these things. Let us say we are just ignoring the removed numbers. The examples look like this after ignoring the numbers we removed:


3
3

1 2 3 4
1 2 3 4

1 5
1 5

So, after removing the last X numbers from the first permutation, the numbers in both permutations must have the same order.

The solution is then to find the maximum Y, such that the first Y numbers of the first permutation are in the same order as they appear in the second permutation. This can be done linearly by using two pointers as the following code:

int solve(int n, int*p1, int*p2) 
{
int x = 0;
int y = 0;

while (x < n) {
while ( (y < n) && (p1[x] != p2[y]) ) {
y++;
}
if (y >= n) {
break;
}
x++;
}
return n-x;

}

Div1 B / Div2 D

linky

So, as I finish writing the explanation for A, I learn that I passed B. All great.

I had issues at first because it seemed like most approaches would be difficult to implement fast.

There are things to consider, there may be cycles when finding closest distances, so it is not going to be your standard dynamic programming problem. Most shortest path algorithms can be a bit heavy to repeat 100000 times. It is best to precalculate things. Even precalculating, I think Dijkstra would not work well. So we need some sort of dp.

Note that the constraint for k_i is uselessly large. Every round, you shall need to visit at most n-1 cities, so there is no need to change cars more than n-1 times.

Let us imagine k=0, so we cannot really change cars. We can still pick any car we want to do all the round though. So, first calculate for each pair of cities (i,j) the minimum path between them using a given car. This is Floyd-Warshall's specialty. After that, for each pair (i,j) pick the car that gives the minimum distance travelled. Remember the best distance possible using any car (without changing), for each (i,j).

The any car bit was my savior, because it can simplify things up later. Let us now find F(i,j,K). The number of ways to move from city i to j, switching cars at most K times, and starting with any car and finishing with any car. The dynamic programming trick involves thinking of a city X. Let us say that you do a car change at city X. Then the minimum time would be: F(i,x,0)+F(x,j, K-1). Because, you can make (K-1) more changes between x and j. Since F assumes the starting and finishing car can be anything, it is just the same as performing a change.

Thus we only need a loop of n-1 steps that tries all values for x to precalculate all the values we will ever need of F(i,j,K).

int n,m,r; 

int road[60][60][60];
int s[100000];
int t[100000];
int k[100000];

const char BINF = 0x4F; //I do this so I can do memset to
const int INF = 0x4F4F4F4F; // int in INF.


int dist[61][61][61][61];

void solve()
{
assert(INF > 50*1000000);
memset(dist, BINF, sizeof(dist));

// first without changing, floyd warshall.
for (int car=0; car<m; car++) {
for (int i=0; i<n; i++) {
for (int j=0; j<n; j++) {
dist[i][j][ car ][0] = road[car][i][j];
}
}
for (int x=0; x<n; x++) {
for (int i=0; i<n; i++) {
for (int j=0; j<n; j++) { //O(x^4)
int y= dist[i][x][car][0] + dist[x][j][car][0];
dist[i][j][ car ][0] = min( dist[i][j][car][0], y);
}
}
}
}
//Save optimal ways if you could use any car
for (int i=0; i<n; i++) {
for (int j=0; j<n; j++) {
dist[i][j][m][0] = INF;
for (int car=0; car<m; car++) { //O(x^3)
dist[i][j][m][0] = min(dist[i][j][m][0], dist[i][j][car][0]);
}
}
}
for (int changes = 1; changes <= n-1; changes++) {
//This dp looks a lot like Floyd, doesn't it?
for (int x=0; x<n; x++) {
for (int i=0; i<n; i++) {
for (int j=0; j<n; j++) { //O(x^4)
// So, we first move from i to x using the best car we like.
// Then we move from x to j using the best cars in {changes-1}
int y = dist[i][x][m][0] + dist[x][j][m][changes-1];
dist[i][j][m][changes] = min(dist[i][j][m][changes], y);
}
}
}
}

for (int i=0; i<r; i++) {
int res = dist[s[i]][t[i]][m][ min(k[i], n-1) ];
cout << res<<endl;
}

//O(x^4 + r)
}

Div1 C / Div2 E

linky

So, just as I finished writing B's explanation, I found out I failed C. Well, my solution was a little far-fetched to begin with. I tried something crazy nesting BFS inside a Dijkstra. At this moment I am not sure if I failed because the idea is wrong or because of a mistake in implementing the idea, such is life.

I exceeded the time limit, but then again I could swear I was visiting each road at most once. Hmnn.

Addendum

I had tons of issues when attempting to write this. blogger was ignoring my commands. To tell you it has been 30 minutes since I actually finished the post. It turns out that the lame new blogger interfaces omits syntax error mistakes in small screens. Because mobile computing is too novel for the developers. I almost lost 2/3 of all I wrote. The mountain of suck in the new blogger is really terrible.

Email ThisBlogThis!Share to XShare to Facebook
Posted in codeforces, explanation | 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)
      • SRM 544: Heh
      • Google Codejam round 2 - yay!
      • Topcoder SRM 543 - The non-fail shock
      • Code learn code learn code redux
      • Learn to code? Why not?
      • Codeforces round #119
      • SRM 542 - Lucky
      • One week, 4 editorials
    • ►  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