## Editorial for IOI '16 P1 - Detecting Molecules

**only**when stuck, and

**not to copy-paste code from it**. Please be respectful to the problem author and editorialist.

**Submitting an official solution before solving the problem yourself is a bannable offence.**

**Subtask 1** is a special case. Iterate all possible , and try to take exactly molecules.

**Subtask 2** is a special case. Iterate all possible , try to take exactly molecules of minimal weight and exactly molecules of maximal weight.

**Subtasks 3 and 4** may be solved using dynamic programming. The task is a classic knapsack problem. Use of time, and of space.

You may optimize the dynamic programming, use `bitset`

and you'll pass **Subtask 5**.

We suggested, a contestant who solves **Subtasks 5 and 6** will invent a greedy approach. If you implement greedy in , you'll pass only **Subtask 5**. Good time to pass **Subtask 6** is .

There are 3 correct greedy solutions. All of them start with sorting the array of weights in nondecreasing order.

**Greedy 1.** Let fix , number of molecules to take. We can choose set of size with sum in iff and . Where is partial minimums on prefixes and is partial maximums on suffixes. Both of them may be precalculated in .

*Proof.* Let's take minimal possible molecules, its summary weight does not exceed . Let's change the set smoothly from " minimal molecules" to " maximal molecules". One step: drop any one molecule, and take any other. Each step changes the sum by at most . The last value of the sum is at least . So one of the intermediate steps gives . ■

**Greedy 2.** There exists an answer which forms a segment. Use two pointers to find it in .

*Proof.* Let's fix – number of molecules in the answer. The smallest molecules form the leftmost segment, and the biggest form the rightmost segment. Let's change the set smoothly from "the leftmost segment" to "the rightmost segment". One step: drop the leftmost molecule, and add a new one at the right. ■

**Greedy 3.** There exists an answer which forms a union of prefix and suffix. Use two pointers to find it in .

*Proof.* Let's fix – number of molecules in the answer. The smallest molecules form prefix, the biggest form suffix. Let's change the set smoothly from "prefix" to "suffix". One step: make prefix shorter by one, make suffix longer by . ■

## Comments