Jzoj4788 序列
来源:互联网 发布:美国普通程序员工资 编辑:程序博客网 时间:2024/06/06 05:39
题意:给你a,b两个序列,每次可以在区间[l,r]对每个数加一,求最少的步数使a变成b
注意,整个过程都是在mod 4的意义下的,a,b所有元素的值都在[0,3]之间
我们可以先考虑不存在Mod 4 的情况
我们假设di=max(0,bi-ai)
那么显然,对于一个位置i,我们需要将其操作max(0,di)次
考虑从1开始,我们设f[i]表示将1~i的d清零所需要的最小次数
显然,f[1]=d[1],f[i]=f[i-1]+max(0,d[i]-d[i-1]) (其实这是一个差分的经典应用)
现在我们来考虑Mod 4 的情况,由于有Mod 4 的影响,我们可以将一系列的d[i]变为d[i]+4k
这样在一种情况下会减小答案
若有i<j使得 d[i]-d[i-1]+4<d[j]-d[j-1] 那么,我们就可以将整个[i,j-1]的d都加上4
这样答案就可以减少(d[i]-d[i-1]-dj+dj-1+4)
实际上,我们只需要维护d[i]-d[i-1]=-2和-3的个数即可(-1+4=3 0+4=4显然都不可能)
每次都贪心地去取就可以
#pragma GCC optimize("O3")#pragma G++ optimize("O3")#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;int n,a[1000010],T;int aim(){scanf("%d",&n); int cnt[4]={0},ans=0;for(int i=1;i<=n;++i) scanf("%d",a+i);for(int x,i=1;i<=n;++i){scanf("%d",&x);a[i]=(x-a[i]+4)&3;}for(int i=1;i<=n;++i) ans+=max(0,a[i]-a[i-1]);for(int i=2;i<=n;++i){int j=a[i]-a[i-1];if(j>0){if(cnt[1] && j>1){--cnt[1];++cnt[j];ans-=--j;} else if(cnt[2] && j>2){--cnt[2];++cnt[j];ans-=j-2;}} else ++cnt[j+4];}printf("%d\n",ans);}int main(){ for(scanf("%d",&T);T--;aim()); }
阅读全文
0 0
- 【jzoj4788】【序列】
- jzoj4788 序列
- 【JZOJ4788】序列
- JZOJ4788. 序列
- Jzoj4788 序列
- NOIP提高组【JZOJ4788】序列
- JZOJ4788. 【NOIP2016提高A组模拟9.17】序列
- 【JZOJ4788】【NOIP2016提高A组模拟9.17】序列
- 序列
- 序列
- 序列
- 序列
- 序列
- 序列
- 序列
- 序列
- 序列
- 序列
- 第18篇
- LRU Cache
- 数组
- 算法学习系列2.2
- java知识点总结
- Jzoj4788 序列
- Shell---常用命令、常用环境变量、PS1、语系变量、位置变量、预定义变量、数值运算
- 初识Linux
- Anaconda离线安装Keras
- bzoj2120: 数颜色(带修莫队)
- 约瑟夫环问题
- 函数调用对stack的影响
- 微信里不能存localStorage怎么办
- 面向对象程序设计上机练习一(函数重载)