Baltic OI 2010 - Candies
Author: Andi Qu
The official solution runs in time, but we can use bitsets to solve this problem in time.
Firstly, instead of changing the number of candies in a package, we can say that Kristian first discards a package and then adds a new one.
Observation 1
After discarding a package, if Kristian can fulfill distinct orders, he can add a package so that he can fulfill distinct orders.
Why is this true?
Think about what happens when we use a bitset to do knapsack DP. Imagine the current bitset storing which orders Kristian can fulfill is B
and we're at a package with a[i]
candies.
To transition, we simply do B |= B << a[i]
.
Thus, if the added a[i]
is sufficiently large, Kristian can double the number of orders he can fulfill.
This means that the package discarded must be the one that yields the most orders Kristian can fulfill when it's discarded.
We can do knapsack DP times (considering discarding each package) to find this package in time.
Observation 2
If there are 2 subsets of candies and , the new package can't have candies, since the number of packages Kristian can fulfill won't double in that case. Note that can be the empty set.
The number of candies in the new package must therefore be the smallest positive integer that can't be expressed as for two subsets of candies and .
To find this number, we can do knapsack DP again, but this time using both a[i]
and -a[i]
instead of just a[i]
.
This knapsack DP runs in as well, which is fast enough for 100 points.
Code
1#include <bits/stdc++.h>2#define FOR(i, x, y) for (int i = x; i < y; i++)3using namespace std;45int a[100];67int main() {8 iostream::sync_with_stdio(false);9 cin.tie(0);10 int n;
Join the USACO Forum!
Stuck on a problem, or don't understand a module? Join the USACO Forum and get help from other competitive programmers!