我们有一个n个正整数的数组。可接受的移动是将所有元素增加1或2或5,除了一个元素。我们需要找出最小数量的操作,以使所有数组元素的数量相等。
搜索后我发现了一种方法:
但是这种方法在这个测试用例中失败了:
数组:1,5,5
最少操作次数:3(1,5,5
- > 1,6,6
- > 6,6,11
- > 11,11,11
)。
按照上述方法,我得到了4。
有人能提出正确的方法吗?
这是我的源代码:
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
#include <climits>
using namespace std;
int input[10000];
int input1[10000];
int dp[4][1001];
int parent[4][1001];
int coins[4]={0,1,2,5};
int operation=0;
int main() {
int t,n,i,j,count,sum,diff,prevdiff,min;
for(i=1;i<1001;i++)
{
dp[0][i]=INT_MAX;
parent[0][i]=INT_MAX;
}
for(i=0;i<4;i++)
{
dp[i][0]=0;
parent[i][0]=-1;
}
for(i=1;i<1001;i++){
for(j=1;j<4;j++){
dp[j][i]=dp[j-1][i];
parent[j][i]=parent[j-1][i];
if(i>=coins[j]&&dp[3][i-coins[j]]<INT_MAX){
if(dp[3][i-coins[j]]+1<dp[j][i]){
dp[j][i]=dp[3][i-coins[j]]+1;
parent[j][i]=j;
}
}
}
}
cin>>t;
while(t>0){
cin>>n;
min=INT_MAX;
for(i=0;i<n;i++)
{
cin>>input[i];
if(input[i]<min){
min=input[i];
}
//input1[i]=input[i];
}
//sort(input,input+n);
count=0;
sum=0;
for(i=0;i<n;i++){
count=count+dp[3][input[i]-min];
}
cout<<count<<endl;
t--;
}
/*
for(i=1;i<1001;i++){
if(dp[3][i]!=minCoins(i))
cout<<dp[3][i]<<" "<<minCoins(i)<<endl;
}
*/
return 0;
}
答案 0 :(得分:4)
您发现的方法不适用于由1,2和5组成的元素集。正如您所说,对于1, 5, 5
,该方法会产生4个操作(对于&#34)硬币改变&#34;),例如:
1, 5, 5
- &gt; 1, 3, 5
- &gt; 1, 1, 5
- &gt; 1, 1, 3
- &gt; 1, 1, 1
为了均衡所有元素,将除1个元素之外的所有元素增加1,2或5,与将一个元素减少相应的值基本相同(参见this answer)。如果您以这种方式查看问题,那么它等于this问题。
后一问题的answer解释了仅考虑最小元素和非最小元素之间的差异是不够的。您还必须考虑所有元素与最小元素的差异 - 1和最小元素 - 2.对于1, 5, 5
,这会导致例如以下操作:
1, 5, 5
- &gt; 0, 5, 5
- &gt; 0, 0, 5
- &gt; 0, 0, 0
1, 5, 5
- &gt; -1, 5, 5
- &gt; -1, 0, 5
- &gt; -1, -1, 5
- &gt; -1, -1, 0
- &gt; -1, -1, -1
正如您所看到的,对于您的示例,考虑所有元素和最小元素之间的差异 - 1给出了均衡所有元素所需的最小操作数,即3。
您应该调整代码以反映这种方法。
答案 1 :(得分:1)
将一个数字除以1,2或5之外的所有数字都等于将该数字除以1,2或5的相同。因此,此问题可以转换为另一个问题,其中-
我们希望仅使用1个操作来使所有数字相等,即将特定数字减少1,2或5。
为解决此问题,我们可以在数组中找到最小数目。所有数字的最终值将为[min(Array)-4, min(Array)]
。我们可以迭代所有5个值,对于每个值,我们可以找到使所有元素均达到所选值的最小移动次数。最后,在每个测试用例中获取所有5个答案中的最小值。那将是结果。这是我的C ++代码-
#include<bits/stdc++.h>
using namespace std;
#define int long long int
signed main(){
int t;
cin>>t;
while(t--){
int n, res = INT_MAX, mini = INT_MAX, ans, temp;
cin>>n;
int A[n];
for(int i=0;i<n;i++){
cin>>A[i];
mini = min(mini, A[i]);
}
for(int i=mini-4;i<=mini;i++){
ans = 0;
for(int j=0;j<n;j++){
temp = A[j]-i;
temp = temp/5+(temp%5)/2+(temp%5)%2;
ans += temp;
}
res = min(ans, res);
}
cout<<res<<"\n";
}
return 0;
}