Codeforces Round #353 (Div. 2) C. Money Transfers (思维)

原题请戳这里

题意:

n个银行成环形排列。每个银行有一定的余额ai,每次可以在任意相邻的银行间转账。问

最少需要经过多少次转账使得所有银行的余额都为0.

 

分析:

由于所有银行的余额总数为0,则若把整个环看成一段,需要n-1次使所有余额为0。

把ai分为k个sum=0的部分,每部分的长度为li,使每个部分所有银行清零需要li-1步。n个

银行清零总共需要n-k步。

因此即是求(n-k)min,那么k值越大越好。

考虑前缀和,若sum[i]==sum[j],则区间[i+1,j]必定和为0,且[j+1,n]和[1,i]区间的sum也为0。

求出前缀和出现最多的次数,即是可以分成的最多的片段和为0的个数。

 

 1 #include<bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 typedef long long ll;
 6 
 7 ll a[100005];
 8 map<ll,int> mp;
 9 
10 int main()
11 {
12     int n;
13     while(~scanf("%d",&n))
14     {
15         mp.clear();
16         ll sum = 0;
17         int ans = n-1;
18         for(int i=0;i<n;i++)
19         {
20             scanf("%I64d",&a[i]);
21             sum += a[i];
22             mp[sum]++;
23             ans = min(ans,n-mp[sum]);
24         }
25         printf("%d\n",ans);
26     }
27     return 0;
28 }

 

posted @ 2016-05-28 16:29  fukan  阅读(192)  评论(0编辑  收藏  举报