[JZOJ4788] 【NOIP2016提高A组模拟9.17】序列
题目
描述
题目大意
一个序列,每次可以使一段区间内的所有数加一(模四)。
问最少的操作次数。
思考历程
一看这题目,诶,这不就是那道叫密码锁的题目吗?
然后随便打一打,样例过了,就再也没有思考这一题。
正解
其实我的想法完全错了。
因为这题只能加,不能减啊!
于是就得考虑另一个方法。
题目可以转成这样的问题:给你一个数列,你可以预先给其中的数加四,然后每次对一个区间进行减一操作,问最少的操作数。
显然,如果已经加四了,就是一道大水题(好像叫……粉刷栅栏)?
我们先不考虑加四,那么答案就是∑max(ai−ai−1,0)\sum{max(a_i-a_{i-1},0)}∑max(ai−ai−1,0)
然后我们考虑加四会有什么影响。
现在我们考虑一下,假设有两个高地为lll和rrr,中间的比较低,要把它们降下来,能不能通过抬高中间的,使得操作数尽量小呢?
然后开始按照lll和l+1l+1l+1之差和r−1r-1r−1和rrr之差分类讨论。
接着就可以发现,只有(−3,3)(-3,3)(−3,3)(−2,3)(-2,3)(−2,3)(−3,2)(-3,2)(−3,2)的情况是有意义的。
于是我们扫一扫有没有这样的东西,减去它们的贡献就好了。
要注意,如果一起做,有可能搞完了(−2,3)(-2,3)(−2,3),就没办法搞(−3,3)(-3,3)(−3,3)了。
由于(−3,3)(-3,3)(−3,3)更优,所以先从左到右将它给搞掉。
接着重新搞剩下两种。
然后就可以做出来了,说实在的,这方法让我醉了……
还有一种比较强大的做法,没有分类讨论。
刚开始的操作是一样的,同样是计算出一个暂时的答案。
然后从前往后扫,如果现在走的是下坡路,就将高度差ai−ai−1+4a_i-a_{i-1}+4ai−ai−1+4存入一个桶中。
如果在走上坡路,记高度差为xxx,就在桶种找小于xxx的第一个有值的,记为jjj。
如果找到了就让答案减去x−jx-jx−j,然后xxx在桶中的值减一,jjj在桶中的值加一。
这样就可以计算出答案了。
具体原因什么的……感觉上有些玄学,我是感性理解的。
代码
using namespace std;
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 100010
int n;
int a[N],c[N];
int las[N];
int main(){
int T;
scanf("%d",&T);
while (T--){
scanf("%d",&n);
for (int i=1;i<=n;++i)
scanf("%d",&a[i]);
for (int i=1;i<=n;++i){
int x;
scanf("%d",&x);
a[i]=(x-a[i]+4)%4;
}
int ans=0;
for (int i=0;i<=n;++i){
ans+=max(a[i+1]-a[i],0);
c[i]=a[i+1]-a[i];
}
memset(las,255,sizeof las);
int cnt2=0,cnt3=0;
for (int i=0,j=-1;i<=n;++i)
if (c[i]==-3){
cnt3++;
las[i]=j;
j=i;
}
else if (c[i]==3 && cnt3){
cnt3--;
c[j]=c[i]=0;
j=las[j];
ans-=2;
}
cnt3=0;
for (int i=0;i<=n;++i)
if (c[i]==-2)
cnt2++;
else if (c[i]==-3)
cnt3++;
else if (c[i]==2 && cnt3)
cnt3--,ans--;
else if (c[i]==3 && cnt2)
cnt2--,ans--;
printf("%d\n",ans);
}
return 0;
}
using namespace std;
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 100010
int n;
int a[N];
int buc[4];
int main(){
int T;
scanf("%d",&T);
while (T--){
scanf("%d",&n);
for (int i=1;i<=n;++i)
scanf("%d",&a[i]);
for (int i=1;i<=n;++i){
int x;
scanf("%d",&x);
a[i]=(x-a[i]+4)%4;
}
int ans=0;
for (int i=1;i<=n;++i)
ans+=max(a[i]-a[i-1],0);
memset(buc,0,sizeof buc);
for (int i=1;i<=n;++i)
if (a[i-1]>a[i])
buc[a[i]-a[i-1]+4]++;
else{
int j=0;
for (;j<a[i]-a[i-1];++j)
if (buc[j])
break;
if (buc[j]){
buc[j]--,buc[a[i]-a[i-1]]++;
ans-=a[i]-a[i-1]-j;
}
}
printf("%d\n",ans);
}
return 0;
}
总结
分类讨论是一种很恶心的方法……
另一种说法叫做:面向数据编程
[JZOJ4788] 【NOIP2016提高A组模拟9.17】序列的更多相关文章
- 【JZOJ4788】【NOIP2016提高A组模拟9.17】序列
题目描述 输入 输出 样例输入 1 5 2 1 3 0 3 2 2 0 1 0 样例输出 1 数据范围 解法 考虑没有模的情况,问题就仅仅只是简单的差分问题(广告铺设): 设r[i]是第i位需要加的次 ...
- 【JZOJ4787】【NOIP2016提高A组模拟9.17】数格子
题目描述 输入 输出 样例输入 1 10000 3 10000 5 10000 0 0 样例输出 1 11 95 数据范围 每个测试点数据组数不超过10组 解法 状态压缩动态规划. 设f[i][j]表 ...
- 【NOIP2016提高A组模拟9.17】序列
题目 分析 首先用\(a_i\)表示达到目标的步数\(B_i-A_i(mod 4)\) 根据粉刷栅栏,先不管mod 4的情况,答案就是\(\sum\max(a_i-a_{i+1},0)\) 那我们刚才 ...
- NOIP2016提高A组模拟9.17总结
第一题,典型的隔板问题, 但是我忘记隔板问题怎么打,一开始在花了1小时,还是没想出来,果断弃疗, 最后的40分钟,我打完了第二题,接着又用了20分钟推敲出一种极其猥琐的式子来代替,可惜预处理的阶乘忘记 ...
- 【NOIP2016提高A组模拟9.17】数格子
题目 分析 设表示每一行的状态,用一个4位的二进制来表示,当前这一行中的每一个位数对下一位有没有影响. 设\(f_{i,s}\)表示,做完了的i行,其状态为s,的方案数. 两个状态之间是否可以转移就留 ...
- 【NOIP2016提高A组模拟9.17】小a的强迫症
题目 分析 题目要求第i种颜色的最后一个珠子要在第i+1种颜色的最后一个珠子之前, 那么我们从小到大枚举做到第i种,把第i种的最后一颗珠子取出,将剩下的\(num(i)-1\)个珠子插入已排好的前i- ...
- 【NOIP2016提高A组模拟8.17】(雅礼联考day1)总结
考的还ok,暴力分很多,但有点意外的错误. 第一题找规律的题目,推了好久.100分 第二题dp,没想到. 第三题树状数组.比赛上打了个分段,准备拿60分,因为时间不够,没有对拍,其中有分段的20分莫名 ...
- 【NOIP2016提高A组模拟8.17】(雅礼联考day1)Binary
题目 分析 首先每个数对\(2^i\)取模.也就是把每个数的第i位以后删去. 把它们放进树状数组里面. 那么当查询操作, 答案就位于区间\([2^i-x,2^{i-1}-1-x]\)中,直接查询就可以 ...
- 【NOIP2016提高A组模拟8.17】(雅礼联考day1)Value
题目 分析 易证,最优的答案一定是按\(w_i\)从小到大放. 我们考虑dp, 先将w从小到大排个序,再设\(f_{i,j}\)表示当前做到第i个物品,已选择了j个物品的最大值.转移就是\[f_{i, ...
随机推荐
- 探索NDIS HOOK新的实现方法(1)
NDIS HOOK是专业级防火墙使用的一种拦截技术,NDIS HOOK的重点是如何获得特定协议对应NDIS_PROTOCOL_BLOCK指针,获得了该指针,接下来就可以替换该协议所注册的收发函数,而达 ...
- Centos搭建http代理服务器(无密码验证)
一.安装shadowsocks yum install python-setuptools && easy_install pip pip install shadowsocks 二. ...
- 2019 牛客多校第五场 B generator 1
题目链接:https://ac.nowcoder.com/acm/contest/885/B 题目大意 略. 分析 十进制矩阵快速幂. 代码如下 #include <bits/stdc++.h& ...
- 拾遗:Perl 在 Shell 脚本编程中的应用
Perl 对我用途,仅是作为 Shell 脚本中的文本处理器:在较大的软件工程里,更多的是使用 C.go 等编译型语言. Perl 是一种历史比较悠久的动态编程语言,在各种类 Unix 系统中得到了应 ...
- kubernetes session and 容器root权限
session保持 如何在service内部实现session保持呢?当然是在service的yaml里进行设置啦. 在service的yaml的sepc里加入以下代码: sessionAffinit ...
- Spring Cloud Feign设计原理
什么是Feign? Feign 的英文表意为“假装,伪装,变形”, 是一个http请求调用的轻量级框架,可以以Java接口注解的方式调用Http请求,而不用像Java中通过封装HTTP请求报文的方式直 ...
- sql2000行转列 转过来的测试完也不知那个网站去哪了 没法写出处了
ALTER procedure dbo.CommonRowToCol ) as begin --必须包含colname列和result列(不区分大小写), --除colname列和result列 其余 ...
- uoj192 【UR #14】最强跳蚤
题目 和成爷达成一致,被卡随机的话就是过了 考虑一个完全平方数的所有质因子次幂一定是偶数,于是对于每一条边我们都只保留其出现次数为奇数的质因子 注意到有一个点的\(w\leq 80\),于是考虑状压质 ...
- Activiti学习笔记5 — 常用API解析
常用API解析: 一.ProcessEngineConfiguration 流程引擎配置对象(配置数据库连接4个大配置和建表策略) 二.ProcessEngine 流程引擎核心对象( ...
- HDFS HA
