Sunday, August 30, 2015

A week with 42

On Saturday morning, TopCoder Open 2015 Round 2D gave everybody the last chance to get into the top 40 and advance to Round 3 (problems, results, top 5 on the left, parallel round results). Of course, getting into top 1 is still better than getting into top 40, so congratulations to tomerun on winning this round!

Here are the statistics on Round 3 advancers by country:

Russian Federation - 42: KankurokuniavskipashkaEndagorionqwerty7877882rfniyaznigmatulVArtemdarnleyyeputonseatmoreSergeiFedorovEgorBaz93Petrhmichmeshanya,LoRd_TaPaKaHandrewztaBelonogovJedi_KnightBurunduk1ilyakormikhailOKRiaDWaWhomo_sapiensknightLMichael_LevinUm_nikKalininNDlougachMerkurevAkhi_Anton,HellKitsuneZloboberEnotUdH-WiNGeRmalcolm734Shapo_aidNikita.PodguzovGassa
Japan - 24: uwiir5hogloidchokudaiKomakiantasnukestqn__mathzerokugisky58kawateasemiexpasi1024Lepton_synasuj_gui0121tomeruntozangezanLayCursesugim48kusano,DEGwerwo[]
China - 22: Blue.Maryxhm1994Sevenkplusjiry_2xyz111ACRushcgy4everzhj1997zyxwvu164nhzp339liympandasky_love_highOIerRobbinwenhanhuangjiangyouno1Meriones,UESTC_elfnesspanjf1987matthew99ajustever86ShizhouxingHillboy
Ukraine - 10: RAVEmanVasyl[alphacom]dzhulgakovK.A.D.RmaksayGlukvlad89LeBronsdyaDeretin
United States - 10: pieguytheycallhimtomlg5293iridescentscott_wuaceofdiamondsxiaowuc1SourSpinachGaytrodexecnerwal
South Korea - 6: Kriiiainu7RRxkcm1700sukh1222xhae
Belarus - 5: touristivan_metelskyforestArtermsubscriber
Poland - 5: EryxPsyhopparysMarcin_smumnbvmar
Croatia - 4: lovroIvLZuzaikatanic
Taiwan - 3: dreamoonShikXDtmt514
South Africa - 2: bmerryHiltonLange
United Kingdom - 2: al13nPaulJefferys
Netherlands - 2: krijgertjedavidv1992
Czech Republic - 2: fhlasekcibulka
Bulgaria - 3: espr1tdanch0anrieff
Slovakia - 2: baklazan4247Xellos0
Latvia - 2: eduardischeAlex_2oo8
Brazil - 2: ffaorafaelhirama
Hungary - 1: ecsirke
Australia - 1: John Dethridge
Georgia - 1: nika
Finland - 1: Sisu
Switzerland - 1: W4yneb0t
Romania - 1: klamathix
Sweden - 1: Gullesnuffs
Bangladesh - 1: shakilaust
Indonesia - 1: handojo1
Mexico - 1: macs
Norway - 1: Im2Good
Iran - 1: EbTech
Canada - 1: zxqfl
Singapore - 1: eugenesh

Codeforces Round 317 ("AimFund Thanks-Round") took place on Saturday evening (problems, results, top 5 on the left). Subscriber has continued his excellent recent form with another victory - great job!

Problem C was a very nice exercise that involved careful reduction to a graph problem, and the observation that the graph problem in question is actually not difficult at all :) The problem statement was: you're given a boolean expression as an AND of several OR-clauses, where each OR-clause is an OR of several terms, and each term is either a variable, or a negation of a variable, and you need to check if the expression evaluates to true for some variable values. Sounds familiar? Well, the familiar problem is NP-complete, whereas this one had one additional restriction: each variable appears at most twice in the formula (including appearances in negated form).

In order for the formula to evaluate to true, each OR-clause has to evaluate to true, meaning that at least one term in each OR-clause has to evaluate to true. If a variable has just one appearance, or if both its appearances are the same (both negated or both not negated), then we can just set its value to make all OR-clauses containing this variable evaluate to true, and forget about those OR-clauses. In case one of the variables has only one appearance in the remaining OR-clauses, we can also set its value, and so on. After this process ends, we're left with some OR-clauses and variables that appear exactly twice in them, once in normal form, and once in negated form.

Here's where graphs come into play: let's make the OR-clauses the vertices of an undirected graph, and connect two OR-clauses with an edge if they share a variable. The problem now asks: is there a way to pick a direction for each edge in this graph in such a way that every vertex has at least one incoming edge?

Had the original problem been formulated in graph terms, the number of solutions would probably be much higher. The remaining graph problem is not difficult, can you see its solution?

In last week's summary, I've promised to explain the solution to Merlin QA, so let me recall the problem statement first. You are given 100 8-dimensional vectors, and you're adding them in one of 100! possible orders, but with a small twist: every time one of the coordinates of the sum is negative, it becomes zero. Here's a 2-dimensional 2-vector example: if you have vectors (5, -2) and (-3, 1), then adding them in the given order yields (0, 0) -> (5, -2) -> (5, 0) -> (2, 1), while adding them in the reverse order yields (0, 0) -> (-3, 1) -> (0, 1) -> (5, -1) -> (5, 0). Your goal is to pick the order of addition that maximizes the sum of coordinates of the resulting vector.

The key idea is: let's consider a slightly different problem! Instead of making each coordinate equal to zero whenever it becomes negative, let's say that we can change any coordinate to zero at any time.

But is this problem really that much different? It's not hard to see that the answers to those problems will always be the same. On one side, setting coordinates to zero whenever they become negative is included in setting them to zero at any desired time, so the answer to the first problem is less than or equal to the answer to the second problem. On the other hand, if we ever reset a positive coordinate to zero or skip resetting a negative coordinate to zero, the answer will not increase, and thus the answer to the second problem is exactly equal to the answer to the first problem!

The newly formulated equivalent problem is much easier to solve, because there's nothing "conditional" happening. For each vector, its contribution to the answer is equal to the sum of its coordinates that will not be reset to 0 after this vector is added. If we consider the last time each coordinate is reset to 0, and reorder the coordinates in decreasing order of that time, then each vector will always contribute a sum of its first k coordinates for some k. Of course, we should now pick k greedily to maximize the contribution. Since we don't know the last time each coordinate is reset to 0, we should consider all 8! possible permutations of coordinates, and apply the above greedy solution to each of them.

Thanks for reading, and check back soon for this week's summary!

No comments:

Post a Comment