[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, ...
随机推荐
- 『BASH』——Hadex's brief analysis of "Lookahead and Lookbehind Zero-Length Assertions"
/*为节省时间,本文以汉文撰写*/ -前言- 深入学习正则表达式,可以很好的提高思维逻辑的缜密性:又因正则应用于几乎所有高级编程语言,其重要性不言而喻,是江湖人士必备的内功心法. 正则表达式概要(ob ...
- subId、slotId、SubscriptionInfo和SubscriptionManager的解释及关系说明
1. subid和slotid(phoneid) slotid(phoneid)是指卡槽:双卡机器的卡槽1值为0,卡槽2值为1,依次类推. subid:SubscriptionId(Subscript ...
- 转:手机端html5触屏事件(touch事件)
touchstart:触摸开始的时候触发 touchmove:手指在屏幕上滑动的时候触发 touchend:触摸结束的时候触发 而每个触摸事件都包括了三个触摸列表,每个列表里包含了对应的一系列触摸点( ...
- 大道浮屠诀---cwRsync同步工具的使用
目的: 在日常生活中,我们有时候会遇到这样类似的问题 ---需要把一台服务器上的某个重要的文件进行备份(拷贝另外的服务器上) ---需要同步系统上的配置文件到其他系统 利用此cwRsync软件可以解决 ...
- 在linux 或docker中使用 system.drawing.common
在dockerfile 中添加 FROM microsoft/dotnet:2.1-aspnetcore-runtime RUN apt-get update RUN apt-get install ...
- Apache2.2+tomcat7 负载均衡配置
思路及步骤:第一步配置tomcat,第二步配置apache 服务器,第三步添加项目到tomcat中并测试 第一步配置tomcat 1,打开 第一个tomcat,conf文件夹下的server.xml ...
- "_CMTimeGetSeconds", referenced from:
CMTime is defined in the CoreMedia.framework. Add that framework to your project.
- 笔记:Python实现二分查找
def search(sequence, number, lower=0, upper=None): if upper is None: upper = len(sequence) - 1 if lo ...
- FaceNet pre-trained模型以及FaceNet源码使用方法和讲解
Pre-trained models Model name LFW accuracy Training dataset Architecture 20180408-102900 0.9905 CASI ...
- 什么是 Hexo?
Hexo 文档 欢迎使用 Hexo,本文档将帮助您快速上手.如果您在使用过程中遇到问题,请查看 问题解答 中的解答,或者在 GitHub.Google Group 上提问. 什么是 Hexo? H ...