题解:CF1969C Minimizing the Sum
首先,每次操作的时候一定是用小的来替换大的,这时数组总和会减少一个值(就是这两个数的差)。
设
每次操作可以将一段连续子串替换为其中的最小值。设操作次数为
(上面的
枚举操作次数
上面的式子中,等号右边表示:当后面连续操作
注意操作次数
时间复杂度
代码:
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=3e5+5,K=15;
int n,k,a[N];
long long sum[N],f[N][K];
long long getsum(int l,int r){return sum[r]-sum[l-1];}
int main()
{
int T; scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
sum[i]=sum[i-1]+a[i];
}
for(int i=0;i<=k;i++)
for(int j=1;j<=n;j++)
{
long long mina=a[j];
for(int l=1;j-l>=1&&i-l>=0;l++) //l operations: [j-l,j](len=l+1)
{
mina=min(mina,(long long)a[j-l]);
f[j][i]=max(f[j][i],f[j-l-1][i-l]+getsum(j-l,j)-mina*(l+1));
}
f[j][i]=max(f[j-1][i],f[j][i]);
}
printf("%lld\n",sum[n]-f[n][k]);
for(int i=0;i<=k;i++)
for(int j=1;j<=n;j++)
f[j][i]=0;
for(int i=1;i<=n;i++)
a[i]=sum[i]=0;
}
return 0;
}