题解 P4677 【山区建小学】
这明显是一道
我们设计
dp[i][j]=min\{dp[k][j-1]+f[k+1][i]\}
这样我们计算出
那么问题来了:怎样计算
(这里需要一点直觉)在区间
f[i][j]=\sum_{k=i}^j |distance(k,mid)|~~~(mid=\frac{i+j}2)
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=510;
const int inf=2e9;
int n,m,a[maxn],f[maxn][maxn],dp[maxn][maxn];
int main()
{
scanf("%d%d",&n,&m);
for(int i=2;i<=n;i++)scanf("%d",a+i),a[i]+=a[i-1];
for(int l=1;l<=n;l++)for(int r=l;r<=n;r++)
{
int mid=(l+r)>>1;
for(int k=l;k<=r;k++)f[l][r]+=abs(a[mid]-a[k]);
}
for(int i=0;i<=n;i++)for(int j=0;j<=m;j++)dp[i][j]=inf;
dp[0][0]=0;
for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)
{
if(j>i){dp[i][j]=0;continue;}
for(int k=j-1;k<=i;k++)dp[i][j]=min(dp[i][j],dp[k][j-1]+f[k+1][i]);
}
printf("%d\n",dp[n][m]);
return 0;
}