棺方数据过了但是民间数据都是9080pts的,求大佬帮忙调一下或者hack一下。
大体思路是枚举翻左边的牌数和右边的牌数,然后翻回对答案有负贡献的牌,找极差最小值。
具体就是从左往右,如果ai>bi记录下来,右边往左搜,ai<bi记录下来,这些翻了会对答案产生负贡献,边上的不翻自然中间的也不翻。然后枚举端点求出最小值。
代码:
#include <bits/stdc++.h>
using namespace std;
int n,m;
int a[1000007];
int b[1000007];
int l,r;
int sum[1000007];
int sum2[1000007];
int minn[1000007];
int maxn[1000007];
int ans;
int main()
{
cin>>n>>m;
for(register int i=1;i<=n;++i)
{
scanf("%d",&a[i]);
}
for(register int i=1;i<=n;++i)
{
scanf("%d",&b[i]);
}
minn[0]=minn[n+1]=INT_MAX/2-1;
b[0]=a[1];
b[n+1]=a[n];
for(register int i=1;i<=n;++i)
{
if(a[i]>b[i])
{
l=i-1;
break;
}
maxn[i]=max(maxn[i-1],b[i]);
minn[i]=min(minn[i-1],b[i]);
sum[i]=min(minn[i],a[i+1])-a[1];
// cout<<sum[i]<<" ";
}
for(register int i=n;i>=1;--i)
{
if(a[i]<b[i])
{
r=i+1;
break;
}
maxn[i]=max(maxn[i+1],b[i]);
minn[i]=min(minn[i+1],b[i]);
sum2[i]=a[n]-max(a[i-1],maxn[i]);
}
for(register int i=0;i<=m;++i)
{
int ll=min(i,l);
int rr=max(n-(m-i)+1,r);
if(maxn[ll]>max(maxn[rr],a[rr-1]))
{
rr=n+1;
}
if(min(minn[ll],a[ll+1])>minn[rr])
{
ll=0;
}
ans=max(ans,sum[ll]+sum2[rr]-max(maxn[ll]-a[n],0)-max(a[1]-minn[rr],0));
}
cout<<a[n]-a[1]-ans;
return 0;
}