Official

E - Lucky bag Editorial by en_translator


Notice that the average of weights of lucky bags \(\bar{x}=\frac{1}{D}(x_1+x_2+\cdots+x_D)=\frac{1}{D}(W_1+W_2+\cdots+W_N)\) are independent of how to divide items.
Here we denote the \(i\)-th item simply by item \(i\).

We consider solving this problem using dynamic programming.
For a subset \(S\) of \(\{1,2,\ldots,N\}\) and an integer \(k\) such that \(1\leq k \leq D\), let \(dp[S][k]\) be the minimum possible \(\displaystyle\sum_{i=1}^k (y_i-\bar{x})^2\) where \(y_1,y_2,\ldots,y_k\) are the weights of lucky bugs, when the items \(g\in S\) are distributed to \(k\) bags. Here, notice that \(\bar{x}\) is the constant uniquely determined by the input, as mentioned above, and is independent of \(S\) and \(k\). The final answer is obtained by dividing \(dp[\{1,2,\ldots,N\}][D]\) by \(D\).

First, regarding \(dp[S][1]\), if there is one bag the only way is to put all the items in the set into the bag, so the sought value is \(\left(\left(\displaystyle\sum_{g\in S}W_g\right)-\bar{x}\right)^2\).
Then, for \(2\leq k\leq D\), let us consider how to find \(dp[S][k]\), assuming that \(dp[S'][k’]\) are already known for all sets \(S'\subset \{1,2,\ldots,N\}\) and positive integers \(dp[S][k]\). Fixing one bag, considering which items to put into it, and taking the minimum of it, this value can be obtained as

\[ dp[S][k]=\min_{T\subseteq S} (dp[(S-T)][k-1]+dp[T][1]). \]

Here, \((S-T)\) denotes the different of set, \((S-T)=(S\backslash T)=\{x|x\in S \land x\notin T\}\). By repeating this for each \(k=2,3,\ldots,D\) in order, the final answer can be obtained.

Now we estimate the complexity. The value \(dp[S][1]\) can be obtained in \(O(N)\) time for each \(S\), for a total complexity of \(O(N2^N)\), which is OK.

Denoting the size of a set \(S\) by \(\lvert S\rvert\), there are \(2^{\lvert S\rvert}\) candidates of sets \(T\subseteq S\). Thus, for a specific \(S\) and \(2\leq k\leq D\), one can evaluate \(dp[S][k]\) from \(dp[S'][k’]\) \((S'\subset \{1,2,\ldots,N\}, k'\leq k-1)\) with \(2^{|S|}\) operations, regardless of \(k\). Since there are \({}_NC_s\) subsets of \( \{1,2,\ldots,N\}\) of size \(s\), noticing the range of \(k\), the overall number of operations is expressed as

\[ \left(\displaystyle\sum_{s=0}^N {}_NC_s\times 2^s \right)\times (D-1) =(2+1)^N\times(D-1)< 3^N\times D. \]

When \(D\leq N\leq 15\), we have \(3^N\times D\leq 2.2\times 10^8\), and each operation is simple addition and comparisons, so it easily fits in the time limit.
Thus, the problem can be solved.

The following are caveats in implementation.

  • It is basically bad idea to store sets using indices; the recommended way is to represent a set as a sequence of bits, expressing which elements are contained.
  • When a set is represented as a bit sequence, the subsets of the set corresponding to the bit sequence \(x\) can be enumerated by starting from \(y=x\) and repeatedly replacing \(y\) with \( (y-1)\& x\) until \(y=0\). (The variable \(y\) spans over bit sequences corresponding to all subsets of \(x\).) Here, \(\&\) denotes the logical product. We omit the proof here.
  • Beware of how many digits to print. For example, if you print only six digits or less, the error may cause WA (Wrong Answer) verdict.

Sample code in C++:

#include <bits/stdc++.h>
using namespace std;

int main(void){
	int n,d,x;
	long double w[15];
	long double ave=0;
	long double dp[(1<<15)][16];
	long double y;

	cin>>n>>d;
	for(int i=0;i<n;i++)cin>>w[i],ave+=w[i];
	ave/=((long double)d);
	for(int i=0;i<(1<<n);i++){
		y=0;
		for(int j=0;j<n;j++){
			if(i&(1<<j))y+=w[j];
		}
		dp[i][1]=pow(y-ave,2);
		for(int j=2;j<=d;j++){
			dp[i][j]=dp[i][j-1]+dp[0][1];
			x=i;
			while(x>0){
				dp[i][j]=min(dp[i][j],dp[i-x][j-1]+dp[x][1]);
				x=(x-1)&i;
			}
		}
	}
	cout<< setprecision(10) <<(dp[(1<<n)-1][d]/((long double)d))<<endl;
	return 0;
}

posted:
last update: