这道题,我想出了一种只对A1≤A2成立的做法,即:计算i≥3后大于A2的Ai,要被A1~A2包含的代价放在数组u[]里,小于A1的Ai,要被包含的代价放在数组d[]里,然后把u[] d[]从小到大排序,再调整A1A2。于是当某一个ui被包含时,所有j<i的uj都已经被包含,d同理。设m′为m减掉已经满足A1≤Ai≤A2的数的个数,然后就有ans=mini+j=m′[ui+dj].
经测试这个做法可以通过所有A1≤A2的点。
但神奇的事情来了,我发现这道题有16个点不满足这个条件,而我的做法却只WA了6个点,所以我猜想这种做法可能对于A1>A2的情况也有一定的正确性。所以我很好奇,为什么这个做法能通过一部分A1>A2的点?该做法经过一些修正能否通过本题?
附上代码和记录。
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 200005, I = 0x3f3f3f3f;
int a[N];
int d[N], u[N], cd, cu;
int alr;
int n, m, ms;
int ans = 1e18;
signed main()
{
scanf("%lld%lld", &n, &m);
for(int i = 1; i <= n; ++i)
{
scanf("%lld", &a[i]);
}
for(int i = 3; i <= n; ++i)
{
if(a[i] > a[2])
{
u[++cu] = a[i] - a[2];
}
if(a[i] < a[1])
{
d[++cd] = a[1] - a[i];
}
if(a[1] <= a[i] && a[i] <= a[2])
{
++ms;
}
}
sort(u + 1, u + cu + 1);
sort(d + 1, d + cd + 1);
m -= ms;
if(m <= 0) ans = 0;
int j;
for(int i = 0; i <= min(m, cu); ++i)
{
j = m - i;
if(j > cd) continue;
ans = min(ans, u[i] + d[j]);
}
printf("%lld", ans);
return 0;
}