1
5
2 1 3 0 3
2 2 0 1 0
1
对于每一个i,它需要改变的次数至少就是 (bi−ai+4) %4
但是改变的次数不一定是 (bi−ai+4) %4
因为,如果对它多4次更改,效果是一样的。
如果,我们将需要改变的次数视为它的高度,
那么,答案就是最少将它们全部覆盖满的次数。
但是,它的高度不是唯一的,是可以随时增加4的。
那我们考虑一下什么情况下面将一段区间的高度都增加4更优?
如果当前的高度比前面的高1,那么前面增加4,就可以减少1的代价
如果当前的高度比前面的高2,那么前面增加4,就可以减少2的代价
如果当前的高度比前面的高3,那么前面增加4,就可以减少3的代价
如果当前的高度比前面的矮1,很显然如果将这个点或者后面的一起增加4是没有意义的。
如果当前的高度比前面的矮2,那么增加4的代价就是2,那就看后面的点的情况。
如果当前的高度比前面的矮3,也是要看后面点的情况。
这样就可以通过贪心来解决这个问题。
#include
#include
#include
using namespace std;
int T,n,a[100003],b[100003],f[100003],ans;
int n2,n3;
int main()
{
scanf("%d",&T);
while(T)
{
T--;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=1;i<=n;i++)
{
scanf("%d",&b[i]);
f[i]=(b[i]-a[i]+4)%4;
}
ans=0;
f[n+1]=0;
for(int i=1;i<=n;i++)
{
f[i]-=f[i+1];
ans+=max(0,f[i]);
}
n3=n2=0;
for(int i=1;i<=n;i++)
{
if(f[i]==3)n3++;
if(f[i]==2)n2++;
if(f[i]==-2)
{
if(n3)
{
n3--;
n2++;
ans--;
}
}
if(f[i]==-3)
{
if(n3)
{
n3--;
ans-=2;
}
else
if(n2)
{
n2--;
ans--;
}
}
}
printf("%d\n",ans);
}
}