Codeforces Round #353 (Div. 2) C. Money Transfers 贪心+前缀和

本文解析了Codeforces竞赛中一道关于银行资产转移的问题,通过寻找前缀和中的重复值来确定最少的资产转移次数,实现从任意银行开始,通过相邻银行间的资产转移使所有银行的资产归零。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://codeforces.com/contest/675/problem/C


题意:

n个银行形成环,一个人在每个银行资产有正有负,现在要求相邻银行之间可以转移资产,使得最后每个银行资产为零。

保证sum=0,求最小转移次数


首先最坏的情况,从第一个银行一直转移到最后一个银行,这样的话 最小转移次数=n-1

如果我们找到一个区间的区间和为零,那么就把原序列划分成两个区间,总的最小转移次数=n-2

以此类推,找到越多区间和为零的不相交小区间,最小转移次数就越少。


怎么找最多的零区间呢?


假设第一个环是从i开始的,那么前缀和S【i】==S【j】表示区间【i+1,j】的和为0,那么下一个环必然是从j+1开始,下一个环的右端点必然是k,满足S【k】==S【j】,同理以后的环都是S【k1】=S【k2】=S【i】....

也就是我们只需要看有多少前缀和值等于s[i],就能找到第一个环从i开始的情况下,能找到最多的零区间


所以我们要找最多的零区间,就变成找所有的前缀和里 重复次数最多的一个


复杂度nlogn

#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include<stack>
using namespace std;

map<long long ,int>mp;
int main()
{
    int n;
    cin>>n;
    long long sum=0;
    int x,ans=0;

    for (int i=1; i<=n; i++)
    {
        scanf("%d",&x);
        sum+=x;
        mp[sum]++;
        ans=max(ans,mp[sum]);
    }
    printf("%d\n",n-ans);
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值