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\) 交换的前提下,最小的

\[\sum_{i=1}^{n}\sum_{j=i+1}^{n}(a_i+a_j)^2+\sum_{i=1}^{n}\sum_{j=i+1}^{n}(b_i+b_j)^2 \]

那么,由该式可以推出

\[\begin{aligned} &=\sum_{i=1}^{n}\sum_{j=i+1}^na_i^2+\sum_{i=1}^{n}\sum_{j=i+1}^na_j^2+\sum_{i=1}^{n}\sum_{j=i+1}^n2a_ia_j+\sum_{i=1}^{n}\sum_{j=i+1}^{n}b_i^2+\sum_{i=1}^{n}\sum_{j=i+1}^{n}b_j^2+\sum_{i=1}^{n}\sum_{j=i+1}^{n}2b_ib_j\\ &=(n-1)\left(\sum_{i=1}^{n}a_i+\sum_{i=1}^{n}b_i\right)+\sum_{i=1}^{n}\sum_{j=i+1}^{n}2a_ia_j+\sum_{i=1}^{n}\sum_{j=i+1}^{n}2b_ib_j\\ &=\left[(n-1)\left(\sum_{i=1}^{n}a_i+\sum_{i=1}^{n}b_i\right)\right]+2\left[\sum_{i=1}^{n}a_i\left(\sum_{j=i+1}^{n}a_j\right)+\sum_{i=1}^{n}b_i\left(\sum_{j=i+1}^{n}b_j\right)\right]\\ &=\left[(n-1)\left(\sum_{i=1}^{n}a_i+\sum_{i=1}^{n}b_i\right)\right]+2\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]\\ \end{aligned} \]

可以发现其中的 \((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\) 不进行交换,那么此时的

\[\begin{aligned} \because&j=a_i+\sum_{k=1}^{i-1}a_k,\\ \therefore&\sum_{k=1}^{i-1}a_k=\sum_{k=1}^{i}a_k-a_i=j-a_i,&\sum_{k=1}^{i-1}b_k=s_{i-1}-\sum_{k=1}^{i-1}a_k=s_i-(j-a_i) \end{aligned} \]

则状态转移为

\[\min\left\{f(i-1,j-a_i)+a_i\times(j-a_i)+b_i\times\left(s_{i-1}-j+a_i\right)\right\} \]

  • 如果 \(a_i\)\(b_i\) 进行交换,那么此时的

\[\begin{aligned} \because&j=b_i+\sum_{k=1}^{i-1}a_k\\ \therefore&\sum_{k=1}^{i-1}a_k=j-b_i,&\sum_{k=1}^{i-1}b_k=s_{i-1}-\sum_{k=1}^{i=1}a_k=s_{i-1}-(j-b_i) \end{aligned} \]

则状态转移为(此时的 \(a_i\)\(b_i\) 交换)

\[\min\left\{f(i-1,j-b_i)+b_i\times(j-b_i)+a_i\times\left(s_{i-1}-j+b_i\right)\right\} \]

\(\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';
}
posted @ 2023-06-17 11:06  Ciaxin  阅读(15)  评论(1编辑  收藏  举报