【JZOJ4788】序列

Description

这里写图片描述

Solution

首先把数列转化成距离目标矩阵所需要的步数,设为 C ,则Ci=(BiAi+4)mod 4

那么这就是一个粉刷栅栏的问题。

首先对 Ci 差分,即 Ci=CiCi+1 。那么答案为 ni=1max(Ci,0)

问题是我们可以给任意一面栅栏的高度增加4。那么如果对一个位置 i 高度增加4,那么Ci+4 Ci14

对于一个区间 (l,r] 高度都增加4,那么影响的只有头尾,也就是 Cl4 Cr+4

Cl=0 是不用理的。

如果 Cl=1 ,那么答案是不会减少的,因为即使 Cr=3 ,所需要的步数还是1。

如果 Cl=2 ,只有在 Cr=3 时,答案才会减少1。

如果 Cl=3 ,那么当 Cr=2 时,答案会减少1, Cr=3 时,答案会减少2。

于是我们正着枚举数列,统计2、3的个数。然后-2与3匹配,-3与3,2匹配。

这里注意-3和3匹配更优,那么如果-2和3匹配了,那么后面的-3是可以使当前的匹配再减少1答案(也就是尽量让-3和3匹配)。

Code

#include<iostream>
#include<cstdio>
#include<cstdlib>
#define fo(i,j,k) for(int i=j;i<=k;i++)
#define fd(i,j,k) for(int i=j;i>=k;i--)
#define N 100001
using namespace std;
int a[N],b[N],c[N];
int main()
{
    int T;
    cin>>T;
    while(T--)
    {
        int n;
        scanf("%d",&n);
        fo(i,1,n) scanf("%d",&a[i]);
        fo(i,1,n)
        {
            int x;
            scanf("%d",&x);
            c[i]=x-a[i];
            if(c[i]<0) c[i]+=4;
        }
        int ans=0;
        fo(i,1,n) c[i]-=c[i+1],ans+=(c[i]>0?c[i]:0);
        int t2=0,t3=0;
        fo(i,1,n)
        {
            if(c[i]==2) t2++;
            if(c[i]==3) t3++;
            if(c[i]==-2)
            {
                if(t3) t2++,t3--,ans--;
            }
            else if(c[i]==-3)
            {
                if(t3) t3--,ans-=2;
                else if(t2) t2--,ans--;
            }
        }
        printf("%d\n",ans);
    }
}
posted @ 2016-09-21 20:17  sadstone  阅读(58)  评论(0编辑  收藏  举报