【CF675C】Money Transfers(离散化,贪心)
2024-10-18 21:16:52
http://www.cnblogs.com/chengsheng/p/5535316.html
题目大意:给你n个银行中的存款(负值表示借贷),是成环的,1跟n相接,这n个数的和为0。可以从i向i的相邻两侧转移存款,问你最少转移多少次,可以让所有银行的存款都为0。
解题思路:n个数的和为0,假设是由k个和为0的区间组成的。假设这些区间的长度为li,那么长度为li的区间需要li-1次转移。那么总共需要l1-1+l2-1+l3-1...+lk-1次转移,因为l1+l2+l3...lk=n,所以总共需要n-k次转移,这个k就是区间和为0的区间个数。我们通过求前缀和sum来统计区间和为0的个数。当sum[i] = sum[j]时,我们知道a[i+1]+...a[j]为0,这个区间和为0。所以我们记录sum=X出现的次数,n-time[X]来更新答案。
此题是均分纸牌(NOIP2002)强化(弱化?)版,此题1与n间可互换
C++自带离散化
排序里面MID没用INT64交了十多次终生遗憾
var c,d:array[..]of longint;
a,s:array[..]of int64;
n,i,ans:longint;
t:int64; function min(x,y:longint):longint;
begin
if x<y then exit(x);
exit(y);
end; procedure qsort(l,r:longint);
var i,j:longint;
mid:int64;
begin
i:=l; j:=r; mid:=s[(l+r) div ];
repeat
while mid>s[i] do inc(i);
while mid<s[j] do dec(j);
if i<=j then
begin
t:=s[i]; s[i]:=s[j]; s[j]:=t;
inc(i); dec(j);
end;
until i>j;
if l<j then qsort(l,j);
if i<r then qsort(i,r);
end; begin
read(n);
// fillchar(s,sizeof(s),);
// fillchar(c,sizeof(c),);
// fillchar(d,sizeof(d),);
//
for i:= to n do read(a[i]);
ans:=n-;
for i:= to n do s[i]:=s[i-]+a[i]; qsort(,n);
for i:= to n do
if (i=)or(s[i]>s[i-]) then c[i]:=c[i-]+
else c[i]:=c[i-]; for i:= to n do inc(d[c[i]]);
for i:= to n do ans:=min(ans,n-d[i]);
writeln(ans); end.
最新文章
- 通过squid 禁止访问/只允许访问指定 网址
- Floyd算法(二)之 C++详解
- Moon.Orm 5.0(MQL版)及之前版本的开源计划
- oracle中的sql%rowcount,sql%found、sql%notfound、sql%rowcount和sql%isopen
- NUC_HomeWork1 -- POJ1068
- Quantum &; r2q
- leetcode面试准备:Decode Ways
- Xml读取异常--Invalid byte 1 of 1-byte UTF-8 sequence
- 有一种acm题目叫做,奇葩!
- VC之美化界面(内容覆盖十分全面,经典)
- iOS 之 自动释放池
- Spring boot——logback 基础使用篇(一)
- ISCC 2018(数字密文)
- Java的selenium代码随笔(7)
- eclipse安装反编译插件(附jad下载)
- unicode编码和utf8编码的区别
- Modelsim SE 破解教程
- swap分区不足ubuntu休眠
- learning ddr mode register MR1
- Codeforces 600E Lomsat gelral(dsu on tree)