这是问题的链接 https://www.hackerrank.com/challenges/equal
我读了它的社论并且无法理解它。如果你没有对hackerrank做任何说明,那么肯定你不会看到它的社论,所以这里有一些社论。
这相当于说,christy可以带走巧克力 一个同事按1,2或5,同时保持其他人的巧克力不受影响 让我们考虑减少同事的巧克力作为一种手术。为了减少操作次数,我们应该尝试使每个同事的巧克力数量等于组中的最小值(分钟)。我们必须通过(A [i] - min)减少第i个人A [i]的巧克力数量。设这个值为x。
This can be done in k operations.
k = x/5 +(x%5)/2 + (x%5)%2
从这里我无法理解
设f(min)是对所有同事进行减少的操作的总和 他们每个巧克力都要分钟。但是,有时f(min)可能不会 总是给出正确的答案。
时也可能是这种情况
f(min) > f(min-1)
f(min) < f(min-5)
因为f(min-5)N次操作超过f(min),其中N是数字 同事。因此,如果
A = {min,min-1,min-2,min-3,min-4}
then f(A) <= f(min) < f(min-5)
有人可以帮助我理解为什么这需要检查f(min),f(min-1),...,f(min-4)
答案 0 :(得分:8)
考虑案例A = [1,5,5]
正如社论所说,用4(2减2)次操作将A
更改为[1,1,1]是最佳的直观,但最好将其更改为[0 ,0,0]与3(1减1,2,2减5)操作。
因此,如果min = minimum element in array
,则将所有元素更改为min
可能不是最佳的。
您不理解的部分是为了迎合这种情况,我们知道min
可能不是最佳的min-x
可能更好,但x
有多大?那么 4 。社论说如果我们知道x
最多为4,我们可以简单地强行min
,min-1
... min-4
来查看哪一个是最小的想得太多。
x&lt; = 4
的推理(不证明!)如果x> = 5,那么你必须对所有绝对不值得的元素使用额外的N类型3(减去5)操作。
基本上这不是操作类型的问题,而是因为你需要对所有元素使用相同的操作,在你这样做之后,问题不会减少,相对差异在于当你想要将相对差异设为0时,元素仍然是相同的,你只需花费 N 操作。
换句话说,如果x> = 5,则x-5必须是目标的更佳选择,实际上x%5必须是最佳目标。
(以下是TL; DR部分:版本2)如果您对证明不感兴趣,请跳至上一部分
在编写原始解决方案的过程中,我怀疑 x <= 2 ,我试图在HackerRank上提交代码,该代码仅检查f(min-x) where x <= 2
的最小值,并且它获得了成功。
更正式地说,我声称
如果5&gt; (z-min)%5> = 3且(z-min&#39;)%5 == 0,然后F(min&#39;)&lt; F(分钟) 其中min&#39; = min-x表示x <= 2,F(k)= min#操作元素z成为k
(请注意表示法,我使用的是F()
,它与问题f()
的含义不同
以下是证据:
如果(z-min)%5 = 1 or 2
,那么它至少需要(z-min)/5 + 1
次操作,而(z-min')%5 == 0 needs (z-min')/5 = (z-min)/5 + 1
操作则意味着F(min') = F(min)
如果(z-min)%5 == 3 or 4
,那么它至少需要(z-min)/5 + 2
次操作,而(z-min')%5 == 0 needs (z-min')/5 = (z-min)/5 + 1
操作则意味着F(min') < F(min) (or F(min') = F(min)+1)
所以我们证明
如果5&gt; (z-min)%5> = 3且(z-min&#39;)%5 == 0,然后F(min&#39;)&lt; F(分钟) 其中min&#39; = min-x
现在让我们证明x
我们假设(z-min)%5 >= 3 and (z-min')%5 == 0
,
所以(z-min')%5 = (z-min+x)%5 = ((z-min)%5 + x%5)%5 == 0
现在,如果x >= 3
,那么(z-min)%5
永远不能是&gt; = 3才能生成((z-min)%5 + x%5)%5 == 0
如果x = 2,那么(z-min)%5可以是3;如果x = 1则(z-min)%5可以是4,以满足两个条件:5> (z-min)%5 >= 3 and (z-min')%5==0
因此我们一起展示
如果5&gt; (z-min)%5> = 3且(z-min&#39;)%5 == 0,然后F(min&#39;)&lt; F(分钟) 其中min&#39; = min-x,x <= 2
注意一个人总是可以生成数组P,这样f(min&#39;)&lt; f(min),因为你总是可以重复整数,这可以通过这种方法改进,直到它输出那些整数不能的数字。这是因为对于无法改进的元素,它们总是需要一个以上的操作
例如:设P = [2,2,2,10] f(min)= 0 + 3 = 3,f(min-2)= 3 + 2 = 5
这里10是可以改进的元素,而2不能,所以我们可以在数组中添加10个。每个2将使用另外1个操作来到min' = min-2
,而每个10将保存1个操作以获得min'
。因此,我们只需添加更多10,直到数字(补偿)&#34;浪费&#34; 2:
P = [2,2,2,10,10,10,10,10],则f(min)= 0 + 15 = 15,f(min-2)= 3 + 10 = 13
或只是
P = [2,10,10],f(min)= 6,f(min-2)= 5
(TL的结尾; DR部分!)
<强> EDITED 强>
OMG在HACKERRANK上的测试案例很弱!
故事是我今天早上到办公室时,我一直在想这个问题,并且认为我的代码可能有问题(获得了ACed!)
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int T, n, a[10005], m = 1<<28;
int f(int m){
m = max(0, m);
int cnt = 0;
for(int i=0; i<n;i++){
cnt += (a[i]-m)/5 + (a[i]-m)%5/2 + (a[i]-m)%5%2;
}
return cnt;
}
int main() {
cin >> T;
while(T--){
m = 1<<28;
cin >> n;
for(int i=0; i<n;i++) cin >> a[i], m = min(m,a[i]);
cout << min(min(f(m), f(m-1)),f(m-2)) << endl;
}
return 0;
}
&#13;
你能看到问题吗?
问题是m = max(0, m);
!
确保min-x
必须至少为0,但等等,我上面的证据没有说明min-x
的范围!它确实可能是消极的!
请记住,原始问题是关于&#34;添加&#34;,因此目标没有最大值;当我们将问题建模为&#34;减去&#34;时,目标也没有最小值(但我将其设置为0!)
使用上面的代码尝试此测试用例:
1
3
0 3 3
&#13;
它强制min-x
= 0,所以它给出4作为输出,但答案应为3
(如果我们使用&#34;添加&#34;模型,目标应为10,在[0]上为+5,在[0]上为+5,在[0],[1]上为+5, a [1],a [2])上的+2
所以当我删除行m = max(0, m);
时,所有内容终于正确(我认为......),它允许min-x
得到否定并将3作为正确输出,当然还有新代码得到ACed ......