type
There are n stacks of cards, numbered,..., n respectively. There are several sheets on each heap, but the total number of cards must be multiples of n. You can take a number of cards on either heap and move them.
The rules for the move are: the cards on the heap numbered 1 can only be moved to the heap numbered 2, and the cards taken on the heap numbered n can only be moved to the heap numbered N-1, and the cards on the other heap may be moved to the adjacent left or right heap.
Now it's time to find a way to move, with the fewest number of moves to make as many cards as you can on each heap.
For example, n=4,4 heap card number is: ①9②8③17④6? Move 3 times to achieve the goal: from ③ take 4 cards put to ④ (9 8), from ③ take 3 cards put to ② (9), from ② take 1 cards put to ① (10 10 10 10). Analysis
At first look at this problem, it is true to use greedy algorithm, but to make the least number of moves, in fact, it is necessary to make the number of moves between the two stacks of one or 0 times.
Since the total number of cards in this title is a multiple of N and requires the same number of cards per stack, we can use the "average" for this magical thing.
We can preprocess:
Step 1: Figure out the average;
Step 2:for cycle minus the average.
We can record each pile of cards as a difference from the average n,0 means that the stack has completed the move, not zero or more than n cards.
But what we need to note is that if the card is recorded as 0 in the middle, the pile of cards cannot be ignored (the reason for the reader to think)
In fact, it is very simple, a group of data to know:
5
5 3 1) 5 11
After preprocessing:
0-2-4 0 6
If you ignore 0, your program will output:
3
Obviously wrong, so the middle of the 0 can not be ignored ...
After doing the above, we can move in one direction and be greedy. Implement
This is a simple code, but you need to pay attention to how many times you move.
(The code should be researched by the reader)
#include <cstdio>
int n,a[105],s,tot;
int main ()
{
scanf ("%d", &n);
for (int i=1;i<=n;i++)
{
scanf ("%d", &a[i]);
S+=a[i];
}
S/=n;
for (int i=1;i<=n;i++)//Pre-
a[i]-=s;
for (int i=2;i<=n;i++)
if (a[i-1]!=0)
{
a[i]+=a[i-1];
a[i-1]=0;//actually this sentence completely can not
tot++;
}
printf ("%d", tot);
return 0;
}
P.S. I can't guarantee this code is correct here.
Greedy Algorithm related articles:
1. To say difficult greedy (ii)--boat problem
2. Difficult to say difficult greedy (iii)--part of the knapsack problem
3. Hard-to-say greed (iv.)--Optimal loading problem
4. Greedy to say difficult (v)--Interval point
5. Greedy and hard to say (vi)--interval coverage problem
6. Say difficult greedy (seven)--select disjoint interval
7. Say hard greedy (eight)--optimal scheduling problem