CodeForces 675C Money Transfers(贪心+奥义维护)

  题意:n个银行。 其中存款有+有-。 总和为0。 n个银行两两相邻((1,n),(1,2)...(n-1,n)); 问最少移动几次(只能相邻移动)能把所有数变为0。

  分析:思路很简单,起始答案算它为n,然后每存在一段,这段的和为0(包括就一个0的情况),这个答案就减1。如1 2 3 -6,只有一段,那么答案是4-1=3。如果是3 5 -5 -3,因为第一个和最后一个也算一段,所以共两段,答案是4-2=2。至于为什么这么做呢,因为一段的长度为len,那么从一个点出发遍历这一段需要移动len-1次(这个出发点不需要再遍历),所以每多和为0的一段,答案减1即可。

  那么我们怎么用O(n)来维护呢?不妨先看代码:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4
 5 int a[100000+100];
 6
 7 int main()
 8 {
 9     int n;
10     scanf("%d",&n);
11     for(int i=1;i<=n;i++) scanf("%d",a+i);
12     map<ll,int> M;
13     ll sum = 0;
14     int ans = 1;
15     for(int i=1;i<=n;i++)
16     {
17         sum += a[i];
18         M[sum] ++;
19         ans = max(ans,M[sum]);
20     }
21     cout << n-ans << endl;
22 }

  手动模拟一下就很好理解了,这个代码还有一个巧妙的地方在于,可以解决头尾相连的问题,如果头尾不能够移动,那么最终的答案应该是n-M[0]。具体的仔细想想就明白了,还是挺奥义的- -。

  看着这个O(n)的维护方法,突然想起之前做的某题,http://www.cnblogs.com/zzyDS/p/5650397.html

  

时间: 2024-11-11 20:42:48

CodeForces 675C Money Transfers(贪心+奥义维护)的相关文章

codeforces 675C Money Transfers 贪心

题目链接:http://www.codeforces.com/problemset/problem/675/C 题意: 有n个银行,每个银行有一个账户,账上的钱可能为负或正或0,且n个银行账户的钱和为0,两个相邻银行的账户可以互相转账,1和n也可以,相当于一个圈. 求最少转多少次可使每个账户上的钱都变成0. 思路: 很明显最多转n-1次就可以满足要求了,即随便选一个点,把每个点的值依次加到下一个点,直到该点的前一个点. 那么假如中间有一段和为0的,假如长度为l,那么次数只要l-1,所以每多一个这

Codeforces Round #300——C贪心——Tourist&#39;s Notes

Description A tourist hiked along the mountain range. The hike lasted for n days, during each day the tourist noted height above the sea level. On the i-th day height was equal to some integer hi. The tourist pick smooth enough route for his hike, me

Codeforces 77C 树形dp + 贪心

题目链接:点击打开链接 题意: 给定n个点, 每个点的豆子数量 下面是一棵树 再给出起点 每走到一个点,就会把那个点的豆子吃掉一颗. 问:回到起点最多能吃掉多少颗豆子 思路:树形dp 对于当前节点u,先把子节点v都走一次. 然后再往返于(u,v) 之间,直到u点没有豆子或者v点没有豆子. dp[u] 表示u点的最大值.a[u] 是u点剩下的豆子数. #include <cstdio> #include <vector> #include <algorithm> #inc

Codeforces 788A Functions again - 贪心

Something happened in Uzhlyandia again... There are riots on the streets... Famous Uzhlyandian superheroes Shean the Sheep and Stas the Giraffe were called in order to save the situation. Upon the arriving, they found that citizens are worried about

Codeforces 486C Palindrome Transformation(贪心)

题目链接:Codeforces 486C Palindrome Transformation 题目大意:给定一个字符串,长度N,指针位置P,问说最少花多少步将字符串变成回文串. 解题思路:其实只要是对称位置不相同的,那么指针肯定要先移动到这里,修改字符只需要考虑两种方向哪种更优即 可.然后将所有需要到达的位置跳出来,贪心处理. #include <cstdio> #include <cstring> #include <cstdlib> #include <vec

codeforces 735C Tennis Championship(贪心+递推)

Tennis Championship 题目链接:http://codeforces.com/problemset/problem/735/C --每天在线,欢迎留言谈论. 题目大意: 给你一个 n (2≤n≤10^18),代表一共有n位参加比赛的选手. 游戏规则: ①每次比赛,输的选手将离开赛场 ②相互比赛的选手 他们的获胜的次数相差不能超过1(获胜4次的选手只能跟3或5次的选手比赛) 问题:最终赢得比赛的选手,胜场最多能为多少. 思路: 贪心:①选一名选手让他一直获胜且优先让他参加比赛 ②当

CodeForces 545C Woodcutters (贪心orDP)

[题目链接]:click here~~ [题目大意]: 有n棵树,给出每棵树的位置和高度,然后把树砍掉,树可以向左倒也可以向右倒.输出最多能砍几棵树. [思路]:利用贪心的思想.第一棵树的左边和最后一棵树的右边没树,所以他们向两边倒,然后对于中间的树来说,首先先向左边倒,然后左边距离如果不够的话再向右边倒,向右倒的时候注意更新一下距离. 代码: /* * Problem: CodeForces 545C * Running time: 46MS * Complier: G++ * Author:

CodeForces 520D 又见贪心

//贪心的做法比较明显:取出方格中的数从左往右排列形成一个 m 进制的数,前者想要数最大,则每次取符合条件的最大的数,后者想要数最小,则每次取符合条件的最小的数. //做法也比较暴力:在整个剩余的数形成的集合中两人每次贪心取数,那么就相当于是对剩余的数形成的集合进行搜索,考虑到极端情况:集合里面有很多数,但是只有一个可以取,这时通过加强集合元素的条件(是剩余的数 && (之前能被取出 || 现在能被取出))来缩小集合的大小,但是在数被取出之后需要对集合进行维护(添加元素) //之前感觉写起

Codeforces 700B Connecting Universities - 贪心

Treeland is a country in which there are n towns connected by n - 1 two-way road such that it's possible to get from any town to any other town. In Treeland there are 2k universities which are located in different towns. Recently, the president signe