我正在为下面的洗衣店分配寻找线性时间算法。
洗衣店里有N台机器。他们有无限的能力。现在卸下一辆布料用于清洗并随机分配给每台机器。在这个过程中,经理错过了平衡布料的清洁。现在需要重新平衡。
重新平衡轮次。每次机器最多可以将一块布料转移到每个邻居。机器的邻居我是机器i-1和i + 1(机器1和N每个只有一个邻居,分别是2和N-1)。重新平衡的目标是实现所有机器具有相同数量的布料。
考虑到最初分配给每台机器的布料数量,系统会要求您确定在每台机器具有相同布料数量时达到状态所需的最小轮数,或确定无法进行此类重新平衡。
答案 0 :(得分:0)
设C为布料总数。当且仅当N均分C时才有解决方案。
在这样的解决方案中,每台机器都有正确的C / N布。设c_i是机器i最初保持的布料数量。将机器i的剩余定义为s_i = c_i - C / N.请注意,盈余可能是负面的;这通常被称为英语中的赤字。
定义f_ {i,i + 1} = sum_ {j≤i} s_i并考虑机器i和i + 1进行的交换。从i发送到i + 1的布料数量减去从i + 1发送到i的布料数量必须等于f_ {i,i + 1},这可以通过考虑1..i中的布料数量来看出时间。
声明:最优解的匝数是T = max_i | f_ {i,i + 1} |。显然这个运行时间是必要的,因为| f_ {i,i + 1} |每回合最多减少一个。充分证据是通过T上的归纳。基本情况是当T = 0时。那么所有f也都是零,我们已经完成了。否则,每台机器我f_ {i,i + 1} = T应该发送一块布到i + 1,而每台机器i + 1使得f_ {i,i + 1} = -T应该发送一块布到一世。这些机器至少有一块布料,因为流量表明它们发出的数量超过了它们,并且新配置将T减少了一个。
答案 1 :(得分:0)
public int getMinimumRounds(int[] machines) {
int total = 0;
int N = machines.length;
for (int clothes: machines) {
total += clothes;
}
if (total % N != 0) {
throw new IllegalArgumentException("Not Possible");
}
int target = total / N;
int rounds = 0;
int diff =0;
for (int i = 0; i < N-1; i++) {
diff = machines[i]-target;
machines[i+1] += diff;
rounds = Math.max(rounds, Math.abs(diff));
}
return rounds;
}