arr[i] :表示每个牌堆的纸牌的数目
平均值 :当纸牌数都一样多时,纸牌的数目
从左向右考虑,每堆纸牌有三种状态:
1) arr[i] == 平均值,考虑arr[i+1]
2) arr[i] < 平均值,此时由arr[i+1]移给arr[i]纸牌。 => 移动纸牌数:(平均值 - arr[i])张
注:
考虑此时,arr[i]缺牌,那么i右边的牌堆必然多牌,无论哪堆多牌,必然有由arr[i+1]将牌移给arr[i]的过程。
3) arr[i] > 平均值,此时由arr[i]移给arr[i+1]纸牌。 => 移动纸牌书:(arr[i] - 平均值)张
注:
考虑此时,arr[i]多牌,那么i右边的牌堆必然缺牌,无论哪堆缺牌,必然有由arr[i]将牌移给arr[i+1]的过程。
每个状态下,所做的动作都是必然需要的,没有做无用功,所以结果最优。
更具体的理解,请点击这里
1 //#define HOME
2 #include <iostream>
3 #include <cstdio>
4 #include <cstdlib>
5 #include <cmath>
6 #include <string>
7 #include <algorithm>
8 #include <cstring>
9 #include <set>
10 #include <utility>
11 #include <locale>
12 #include <ctime>
13 using namespace std;
14 const int INF = 0x3f3f3f3f;
15 const int MaxN = 110;
16
17 int N, arr[MaxN], sum;
18
19 void Solve()
20 {
21 int ave = sum / N;
22 int cnt = 0;
23 for (int i = 0; i < N - 1; ++i)
24 {
25 if (arr[i] == ave) continue;
26 if (arr[i] < ave)
27 {
28 arr[i + 1] -= (ave - arr[i]);
29 ++cnt;
30 }else
31 {
32 arr[i + 1] += (arr[i] - ave);
33 ++cnt;
34 }
35 }
36 cout << cnt << endl;
37 }
38
39 int main()
40 {
41 cin >> N;
42 sum = 0;
43 for (int i = 0; i < N; ++i)
44 {
45 cin >> arr[i];
46 sum += arr[i];
47 }
48 Solve();
49
50
51 #ifdef HOME
52 cerr << "Time elapsed: " << clock() / CLOCKS_PER_SEC << " ms" << endl;
53 #endif
54 return 0;
55 }