Yet Another Minimization Problem(CF1637D)
\(\text{Des}\)
You are given two arrays $ a $ and $ b $ , both of length $ n $ .
You can perform the following operation any number of times (possibly zero): select an index $ i $ ( $ 1 \leq i \leq n $ ) and swap $ a_i $ and $ b_i $ .
Let's define the cost of the array $ a $ as $ \sum_{i=1}^{n} \sum_{j=i + 1}^{n} (a_i + a_j)^2 $ . Similarly, the cost of the array $ b $ is $ \sum_{i=1}^{n} \sum_{j=i + 1}^{n} (b_i + b_j)^2 $ .
Your task is to minimize the total cost of two arrays.
\(\text{Sol}\)
由题意可知,要求的值是在将任意的 \(a_i\) 与 \(b_i\) 交换的前提下,最小的
那么,由该式可以推出
可以发现其中的 \((n-1)\left(\sum_{i=1}^{n}a_i+\sum_{i=1}^{n}b_i\right)\) 是作为一个定值出现的,所以我们只需要将 \(\left[\sum_{i=1}^{n}a_i\left(\sum_{j=1}^{i-1}a_j\right)+\sum_{i=1}^{n}b_i\left(\sum_{j=1}^{i-1}b_j\right)\right]\) 最小化即可。
这一点,利用动规解决。
在由第 \(i-1\) 个状态向第 \(i\) 个状态转移的时候,我们无法确定的是 \(\sum_{j=i+1}^na_i\) 和 \(\sum_{j=i+1}^nb_i\) 的值(因为其中可能存在交换)。
那么因为考虑到 \(\sum_{i=1}^na_i\) 的值并不大,所以可以将 \(\sum_{i=1}^{n}a_i\) 加入状态。
又因为交换的为 \(a_i\) 与 \(b_i\),可以发现在相同范围内的区间和的和(即 \(\sum_{i=l}^{r}a_i+b_i\))也是一个定值,那么就可以求出对应的 \(b\) 的区间的和。
此时,我们设计状态为 \(f(i,j)\) 表示为考虑前 \(i\) 位,\(\sum_{k=1}^{i}a_k=j\) 时的最小值,
那么对于状态的转移,
令 \(s_i=\sum_{k=1}^{i}(a_i+b_i)\) 的值。
- 如果 \(a_i\) 与 \(b_i\) 不进行交换,那么此时的
则状态转移为
- 如果 \(a_i\) 与 \(b_i\) 进行交换,那么此时的
则状态转移为(此时的 \(a_i\) 与 \(b_i\) 交换)
\(\text{CODE}\)
void solve() {
ans=minn=0;
memset(f,0x7f7f7f,sizeof(f));
f[0][0]=0;
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++) {
cin>>b[i];
k[i]=k[i-1]+max(a[i],b[i]);
sum[i]=sum[i-1]+a[i]+b[i];
ans+=a[i]*a[i]+b[i]*b[i];
}
ans*=(n-1);
for(int i=1;i<=n;i++) {
for(int j=1;j<=k[i];j++) {
if (j-a[i]>=0 && sum[i-1]-j+a[i]>=0) {
f[i][j]=min(f[i][j],f[i-1][j-a[i]]+a[i]*(j-a[i])+b[i]*(sum[i-1]-j+a[i]));
}
if (j-b[i]>=0 && sum[i-1]-j+b[i]>=0){
f[i][j]=min(f[i][j],f[i-1][j-b[i]]+b[i]*(j-b[i])+a[i]*(sum[i-1]-j+b[i]));
}
}
}
minn=1e9+7;
for(int j=1;j<=k[n];j++){
minn=min(minn,f[n][j]);
}
cout<<ans+2*minn<<'\n';
}