斜率优化。又是变量名打错看了老半天。
把方差式子展开一下就好了。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxn 3050 #define inf 0x7f7f7f7f7f7f7f7fLL using namespace std; long long n,m,a[maxn],sum[maxn],dp[maxn][maxn],rk[maxn],l,r,q[maxn]; double k(long long x,long long y) { if (sum[x]==sum[y]) return inf; return (double)(rk[x]-rk[y])/(sum[x]-sum[y]); } void k_dp() { for (long long i=1;i<=n;i++) dp[1][i]=sum[i]*sum[i]; for (long long i=2;i<=m;i++) { l=r=1;q[l]=i-1; for (long long j=i-1;j<=n;j++) rk[j]=dp[i-1][j]+sum[j]*sum[j]; for (long long j=i;j<=n;j++) { while ((r-l) && (k(q[r-1],q[r])>k(q[r],j))) r--; q[++r]=j; while ((r-l) && (k(q[l],q[l+1])<=2*sum[j])) l++; dp[i][j]=dp[i-1][q[l]]+(sum[j]-sum[q[l]])*(sum[j]-sum[q[l]]); } } } long long get_ans() { return dp[m][n]*m-sum[n]*sum[n]; } int main() { scanf("%lld%lld",&n,&m); for (long long i=1;i<=n;i++) {scanf("%lld",&a[i]);sum[i]=sum[i-1]+a[i];} k_dp(); printf("%lld\n",get_ans()); return 0; }