CODE[VS] 1098 均分纸牌 ( 2002年NOIP全国联赛提高组)

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 }

 

 

转载于:https://www.cnblogs.com/shijianming/p/4833964.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值