Codeforces1254B2 Send Boxes to Alice (Hard Version)(贪心)
题意
n个数字的序列a,将i位置向j位置转移x个(a[i]-x,a[j]+x)的花费为\(x\times |i-j|\),最终状态可行的条件为所有a[i]均被K整除(K>1),求最小花费
做法
\(sum=\sum\limits a\),则\(K|sum\)
- 有\(K1|sum,K2|sum\),若\(K1|K2\),则转移到被K1整除比转移到K2更优。这个是显然的,所以最终可能成为最优解的K个数为\(logsum\le 40\)
对于一个枚举到的K,将\(b[i]=a[i]\% K\)
对于b不为0的位置,我们类似贪心得考虑
仅有前面一个位置pre不合法:因为如果有两个,在之前我们可以合成一个
如果b[i]可以与前一个补满(b[i]可能还会有多余的),考虑从i转移到pre优还是pre转移到i优
如果b[i]不能补满前一个,这个时候我们考虑如果能补满会补到哪里,然后更新一下pre
Code
比赛时调了好久,码风有点奇怪
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef long long ll;
const LL maxn=1e6+9;
const ll inf=0x3f3f3f3f3f3f3f3f;
LL Read(){
LL x(0),f(1); char c=getchar();
while(c<'0' || c>'9'){
if(c=='-') f=-1; c=getchar();
}
while(c>='0' && c<='9'){
x=(x<<3)+(x<<1)+c-'0'; c=getchar();
}return x*f;
}
LL n,T,tot;
ll sum;
LL a[maxn],b[maxn];
ll bel[maxn];
bool Check(ll x){
for(LL i=1;i<=tot;++i) if(x%bel[i]==0) return false;
return true;
}
int main(){
n=Read();
for(LL i=1;i<=n;++i) a[i]=Read(),sum+=a[i];
/*srand(time(NULL));
n=1000000;
for(LL i=1;i<=n;++i) a[i]=rand()%1000001,sum+=a[i];
printf("%lld\n",sum);*/
for(LL i=2,up=sqrt(sum);i<=up;++i) if(sum%i==0){
if(Check(i)) bel[++tot]=i;
if(Check(sum/i)) bel[++tot]=sum/i;
}
if(Check(sum)) bel[++tot]=sum;
// printf("%d\n",tot);
if(sum==0 || sum==1){
puts("-1"); return 0;
}
if(!tot){
puts("0"); return 0;
}
ll ans(inf);
for(LL k=1;k<=tot;++k){
ll x(bel[k]),nw(0),ret(0);
LL l(1),pre(0);
for(LL i=1;i<=n;++i){
b[i]=a[i]%x;
if(!b[i]) continue;
if(nw){
if(x-nw>b[i]){
if((x-nw)*(i-pre)>nw*(i-pre)) ret+=nw*(i-pre),pre=i;
else ret+=b[i]*(i-pre);
nw+=b[i];
}else{
ret+=(std::min(x-nw,nw))*(i-pre);
nw=b[i]-(x-nw);
if(nw) pre=i;
}
continue;
}
nw=b[i];
pre=i;
}
ans=std::min(ans,ret);
// printf("(%lld,%lld)\n",x,ret);
}
printf("%lld\n",ans);
return 0;
}
Codeforces1254B2 Send Boxes to Alice (Hard Version)(贪心)的更多相关文章
- E1.Send Boxes to Alice(Easy Version)//中位数
发送盒子给Alice(简单版本) 题意:准备n个盒子放巧克力,从1到n编号,初始的时候,第i个盒子有ai个巧克力. Bob是一个聪明的家伙,他不会送n个空盒子给Alice,换句话说,每个盒子里面都有巧 ...
- Codeforces Round #601 (Div. 2) E2. Send Boxes to Alice (Hard Version)
Codeforces Round #601 (Div. 2) E2. Send Boxes to Alice (Hard Version) N个盒子,每个盒子有a[i]块巧克力,每次操作可以将盒子中的 ...
- Codeforces Round #601 (Div. 2) E1 Send Boxes to Alice (Easy Version)
#include <bits/stdc++.h> using namespace std; typedef long long ll; ; int a[N]; int n; bool pr ...
- E2. Send Boxes to Alice (Hard Version)
秒的有点难以理解:https://blog.csdn.net/weixin_42868863/article/details/103200132 #include<bits/stdc++.h&g ...
- E1. Send Boxes to Alice (Easy Version)
题解: 保存每个1的位置.然后记录1的总个数cnt,如果存在一个k使得这个k是每个集合的倍数,那么为了使操作次数最小,这个k应该是cnt的质因子.(因为都是每个集合的数目1,使每个集合的数目变为2需要 ...
- Send Boxes to Alice
E. Send Boxes to Alice 首先求出每一个位置的前缀和. 对答案进行复杂度为\(\sqrt{a[n]}\)的遍历,因为最后的答案不可能大于\(\sqrt{a[n]}\) for(ll ...
- Codeforces 1255E Send Boxes to Alice(前缀和+枚举+数论)
我们考虑前缀和sum[i],如果将a[i+1]中的一个塞入a[i]中,则不影响sum[i+1],但是sum[i]++,如果将a[i]中的一个塞入a[i+1],则不影响sum[i+1],但是sum[i] ...
- Alice and Bob(贪心HDU 4268)
Alice and Bob Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tota ...
- HDU 4268 Alice and Bob 贪心STL O(nlogn)
B - Alice and Bob Time Limit:5000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u D ...
随机推荐
- 03、新手必须掌握的Linux命令
Ⅰ. 常用系统工作命令 1. echo 命令 echo命令用于在终端输出字符串货变量提取后的值,格式为"echo [字符串 | $变量]" 例:把指定字符串"LinxuH ...
- Computer Neworking: A Top-Down Approach
目录 Chapter 1: Computer Networks and the Internet 1. What is the Internet? 2. The Network Edge 3. The ...
- 85.webpack的安装失败至成功
webpack怎么安装 1.安装node.js; 2.安装webpack: npm install webpack --save-dev : 注意:webpack 4x以上,webpack将命 ...
- HTML 图像标签(img)
一.标签属性 属性就是一个实体的特性,例如:手机的属性有大小,颜色等,HTML标签也有自己的属性. 使用HTML制作网页时,如果想让HTML标签提供更多的信息,可以使用HTML标签的属性加以设置. 语 ...
- 设计模式 结构型 - 适配器模式 Adapter
Adapter(适配器模式) ---- 加个“适配器”以便于复用 将一个类的接口转换成客户希望的另一个接口.Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作. 应用场景 如果 ...
- mysql新加用户设置权限
1.开通操作权限和表权限 GRANT CREATE,ALTER,DROP,INSERT,UPDATE,DELETE,SELECT ON interface.* TO test1@'%' identif ...
- IDEA编码时卡顿问题
当代码行数超过2000行,甚至更多时会出现编码时卡顿到无法编译的情况,解决方法如下: 方法1:修改IDEA配置参数 找到D:\ideaIU-2019.1.1.win\bin\idea64.exe.vm ...
- Xinetd超级守护进程
Xinetd超级守护进程 00.什么是xinetd服务 xinetd(extended Internet services daemon), 是新一代网络守护进程服务程序, 又叫超级守护进程. 经常用 ...
- Kotlin匿名函数与闭包详解
Lambda表达式实例演练: 继续先来编写一些Lambda表达式相关的代码: 接下来想从上面的字符串数组中找到带有"h"的字符串并打印出来: 如果学习了Java8的Lambda表达 ...
- No root/virtual joint specified in SRDF. Assuming fixed joint
在用MoveIt!配置文件时,加载urdf模型时,显示Success......但没有显示模型,终端显示错误如下: 增加虚拟关节就好.