codeforces 675C C. Money Transfers(贪心)

题目链接:

C. Money Transfers

time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

There are n banks in the city where Vasya lives, they are located in a circle, such that any two banks are neighbouring if their indices differ by no more than 1. Also, bank 1 and bank n are neighbours if n > 1. No bank is a neighbour of itself.

Vasya has an account in each bank. Its balance may be negative, meaning Vasya owes some money to this bank.

There is only one type of operations available: transfer some amount of money from any bank to account in any neighbouring bank. There are no restrictions on the size of the sum being transferred or balance requirements to perform this operation.

Vasya doesn't like to deal with large numbers, so he asks you to determine the minimum number of operations required to change the balance of each bank account to zero. It's guaranteed, that this is possible to achieve, that is, the total balance of Vasya in all banks is equal to zero.

 
Input
 

The first line of the input contains a single integer n (1 ≤ n ≤ 100 000) — the number of banks.

The second line contains n integers ai ( - 109 ≤ ai ≤ 109), the i-th of them is equal to the initial balance of the account in the i-th bank. It's guaranteed that the sum of all ai is equal to 0.

 
Output
 

Print the minimum number of operations required to change balance in each bank to zero.

 
Examples
 
input
3
5 0 -5
output
1
input
4
-1 0 1 0
output
2
input
4
1 2 3 -6
output
3
 
题意:
 
a[i]表示这个人欠第i个银行多少钱,这个人每次只能在相邻的银行之间转账,问最少要转多少次才能使所有的a[i]的值为0;其中1和n的相邻;
 
思路:
 
可以发现,最多需要n-1次,我们可以这样想,把每个a[i]都当成一个独立的集合,围成一个圈,我们的目标是把这些集合合并成0,且操作次数最少,那么怎么才能使操作最少且有达到目标呢?那就是要尽量使集合尽量多,因为合并一个数就至少需要一次操作,一次操作就会减少一个集合,而么操作次数就是集合的减少数目,所以最后的答案就是n-最多的集合数;现在就变成了怎么找最多的集合数目了;
跟前缀和有关,这个就相当于一个区间和为0,要把这个圈的数分成最多的集合就是找前缀和出现的最多的那个次数了;
 
 
AC代码:
 
#include <bits/stdc++.h>
using namespace std;
#define Riep(n) for(int i=1;i<=n;i++)
#define Riop(n) for(int i=0;i<n;i++)
#define Rjep(n) for(int j=1;j<=n;j++)
#define Rjop(n) for(int j=0;j<n;j++)
#define mst(ss,b) memset(ss,b,sizeof(ss));
typedef long long LL;
const LL mod=1e9+7;
const double PI=acos(-1.0);
const int inf=0x3f3f3f3f;
const int N=1e5+25;
int n,a[N];
LL sum[N];
map<LL,int>mp;
int main()
{
    scanf("%d",&n);
    int ans=0;
    Riep(n)
    {
        scanf("%d",&a[i]);
        sum[i]=sum[i-1]+a[i];
        mp[sum[i]]++;
        ans=max(ans,mp[sum[i]]);
    }
    cout<<n-ans<<"\n";

    return 0;
}

 

 
posted @ 2016-05-19 23:24  LittlePointer  阅读(432)  评论(0编辑  收藏  举报