Codeforces Round #353 (Div. 2) C. Money Transfers (思维题)
2016-05-17 20:08
197 查看
题目链接:http://codeforces.com/contest/675/problem/C
给你n个bank,1~n形成一个环,每个bank有一个值,但是保证所有值的和为0。有一个操作是每个相邻的bank之间可以转钱,让你用最少的操作使每个bank的值为0。
一开始没什么思路,看了一下别人的题解,果然还是还是native...
要是让操作次数变少,首先划分和为0的区间个数要尽量多,比如一个区间的长度为k,那么他操作次数为k - 1,所以总的操作次数就是(n - 区间的个数)。
那么要算出区间的个数的话,那就要先算前缀和,比如前缀和sum[r] = x ,sum[l] = x其中(r > l),那么(l , r]之间的和为0。所以我们从1到n遍历一下前缀和,计算其中前缀和相同且次数出现最多的个数就行了。
给你n个bank,1~n形成一个环,每个bank有一个值,但是保证所有值的和为0。有一个操作是每个相邻的bank之间可以转钱,让你用最少的操作使每个bank的值为0。
一开始没什么思路,看了一下别人的题解,果然还是还是native...
要是让操作次数变少,首先划分和为0的区间个数要尽量多,比如一个区间的长度为k,那么他操作次数为k - 1,所以总的操作次数就是(n - 区间的个数)。
那么要算出区间的个数的话,那就要先算前缀和,比如前缀和sum[r] = x ,sum[l] = x其中(r > l),那么(l , r]之间的和为0。所以我们从1到n遍历一下前缀和,计算其中前缀和相同且次数出现最多的个数就行了。
#include <bits/stdc++.h> using namespace std; typedef __int64 LL; map <LL , int> mp; int main() { int n , res = 0; LL sum = 0 , num; scanf("%d" , &n); for(int i = 0 ; i < n ; ++i) { scanf("%I64d" , &num); sum += num; mp[sum]++; res = max(res , mp[sum]); } printf("%d\n" , n - res); }
相关文章推荐
- css float left right 中间空间城数据无法显示
- Codeforces Round #353 (Div. 2) C. Money Transfers 环、贪心、前缀和推广、好题
- jsp 前后台值传递
- jsp编码过程
- SICP 2-31 2-32 SymbolicDiffer
- 算是学完了《Servlet&JSP学习笔记》,立此存照
- jsoncpp解析拼装数组
- jquery validate 自定义验证小数前面9位,小数后面2位的js
- js学习六-闭包
- jquery实现日期的比较
- 沉浸式标题栏样式
- POJ 3132 Sum of Different Primes
- js里==和===的区别
- 《JavaScript程序设计》课堂交流区问题汇总(基础篇)
- javascript笔试题(2)
- js 跨域 post 还有get
- 【剑指offer】两队列实现栈与两栈实现队列
- Life Without Zeros
- AngularJS 学习 之 初体验
- 为什么我从 Python 转战到 Node.js