题目大意:有n个包,其中小包可以装到大的包里,包的大小用数字进行表示,求最小的装包数量。
统计每个数字出现的次数,其中次数的最大值k就是最小的装包数量。答案显然不可能比k小,而把相同大小的包装进不同的大包里显然满足条件。题目中有一句话纠结了半天,“While maintaining the minimal number of pieces you are also to minimize the total number of bags in any one piece that must be carried.” 大概是说让每个大包里的小包的数量的最大值最小吧,也就是要把小包尽可能平均放到这k个大包里,于是就有了有了“排序,以k为等差的序列”这一解法,因为a[i+k] > a[i]。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <cstdio> 2 #include <algorithm> 3 using namespace std; 4 #define MAXN 10000+10 5 6 int a[MAXN]; 7 8 int main() 9 { 10 #ifdef LOCAL 11 freopen("in", "r", stdin); 12 #endif 13 int n; 14 bool first = true; 15 while (scanf("%d", &n) != EOF && n) 16 { 17 for (int i = 0; i < n; i++) 18 scanf("%d", &a[i]); 19 sort(a, a+n); 20 int k = 1, cnt = 1; 21 for (int i = 1; i <= n; i++) 22 { 23 if (i == n || a[i] != a[i-1]) 24 { 25 if (cnt > k) k = cnt; 26 cnt = 1; 27 } 28 else cnt++; 29 } 30 if (first) first = false; 31 else printf(" "); 32 printf("%d ", k); 33 for (int i = 0; i < k; i++) 34 { 35 for (int j = i; j < n; j += k) 36 printf("%s%d", (i==j) ? "" : " ", a[j]); 37 printf(" "); 38 } 39 } 40 return 0; 41 }