链接
题意:
给出A序列,让你构造出B,C序列要求满足:
- B i + C i = A i B_i+C_i=A_i Bi+Ci=Ai
- B序列递增
- C序列递减
使得 ∑ ∣ B i ∣ + ∣ C i ∣ \sum |B_i|+|C_i| ∑∣Bi∣+∣Ci∣最小化
分析:
我们要让B递增,C递减,
∑
\sum
∑那么我们肯定要 满足
B
i
=
B
i
+
1
B_i=B_{i+1}
Bi=Bi+1或者
C
i
=
C
i
+
1
C_i=C_{i+1}
Ci=Ci+1
所以一旦我们选择好
B
1
B_1
B1也就确定了整个序列。
我们看B,C是相反的单调性,不好分析,我们C变成-C这样,C序列也是递增的了,并且对于
∑
∣
B
i
∣
+
∣
C
i
∣
\sum |B_i|+|C_i|
∑∣Bi∣+∣Ci∣答案不变
所以如果
- A i + 1 > A i A_{i+1}>A_{i} Ai+1>Ai那么我们将差值加到B上让 B i + 1 = B i + ( A i + 1 − A i ) B_{i+1}=B_{i}+(A_{i+1}-A_{i}) Bi+1=Bi+(Ai+1−Ai)
- A i + 1 < A i A_{i+1}<A_{i} Ai+1<Ai那么我们将差值加到C上让 C i + 1 = C i + ( A i − A i + 1 ) C_{i+1}=C_{i}+(A_{i}-A_{i+1}) Ci+1=Ci+(Ai−Ai+1)
让正的都加上递增序列,让较少的都加到递减序列。
然后我们将其放去同一个集合,我们可以让其同时移动k,可以左移(-),同样也可以右移(+),使其绝对值和最小,那肯定找到中位数让其左移中位数呀。
ll n, m;
ll a[N];
std::vector<ll> v;
void solve()
{
cin >> n;
for (int i = 1; i <= n; i++){
scanf("%lld",&a[i]);
}
ll A=a[1],B=0;
v.push_back(A);
v.push_back(B);
for(int i=1;i<n;i++){
ll x = a[i+1]-a[i];
if(x>=0) A+=x;
else B-=x;
v.push_back(A);
v.push_back(B);
}
sort(v.begin() , v.end());
ll ans=0;
for(int i=0;i<v.size();i++){
ans += abs(v[i]-v[n]);
}
cout<<ans<<endl;
}