原文:http://blog.csdn.net/Ramay7/article/details/51809977
题目链接:
UVALive 6694 - Toy Boxes
题意:
有
n
个物品,需要分在三个箱子里,每个箱子的花费是
(箱子中物品个数∗箱子中物品的总重量
(箱子重量忽略不计),求总花费最少是多少?
(n≤20000,每个物品的重量≤1000)
分析:
先考虑将其分为两堆的情况。我们需要证明一个结论:分成两堆时一定是连续小的物品在一堆,连续大的在一堆,也就是其中一堆的任意一个物品重量都要小于另一堆。,并且小的那一堆的个数一定要大于大的那一堆的个数。
假设一堆的个数为
x
,重量为
A
,另一堆的个数为
y
,重量为
B
,如果第一堆的每一件物品
xi
的重量都小于第二堆的任意一件物品
yj
,并且
x>y
那么就是“稳定”的了。否则:我们可以通过交换
xi和yj
使得总花费更少。
-
① x<y 且第一堆的每一件物品 xi 的重量都小于第二堆的任意一件物品 yj
从第二堆中任取一个 yj ,重量为 b 放进第一堆中
原有的总花费为:x∗A+y∗B调整后:(x+1)∗(A+b)+(y−1)∗(B−b)=x∗A+y∗B+b∗(x−y)+A+b−B+b=x∗A+y∗B+b∗(x−y)+(2∗b−(B−A))因为 x<y 且第一堆的每一件物品 xi 的重量都小于第二堆的任意一件物品 yj ,那么 B−A>b,2∗b−(B−A)<b ,同时 x−y<−1,b∗(x−y)<−b ,那么b∗(x−y)+(2∗b−(B−A))<0所以调整后更优。 -
② x>y 且第一堆的每一件物品 xi 的重量 a 大于第二堆的一件物品 yj 重量 b
原有的总花费是:x∗A+y∗B交换后的花费是:x∗(A−a+b)+y∗(B−b+a)=x∗A+y∗B+(y−x)∗(a−b)显然调整后更优。
这样子可以粗略的证明了上述结论。对于分成两堆的情况,先排序然后扫一遍即可。那么分成三堆呢?我们可以枚举第一堆的个数 i ,然后二分查找第二堆的个数,因为花费关于个数是一个单峰函数。比较 mid和mid+1 的花费情况。
注意开 long long 。