从题目要求最优解并且是策略性题目首先考虑使用DP,状态变量自然是P和V,表示邮局数和村庄数。D(P,V)表示最优值。然后思考如何转换成最优子问题,单独拿出一个邮局,这个邮局一定管辖了一段连续的村庄,关键是这段村庄在哪个位置,有多少个村庄。所以D(P,V) = max(1<=r<=v-p+1){D(P-1,V-r) + d(v-r+1,v)}
#include<iostream>
#include<memory>
#define Post 31
#define Valley 3001
#define INF 9999999
using namespace std;
int p;
int v;
int value[Post][Valley];
int d[Valley][Valley];
int x[Valley];
int main(){
int i,j,r;
cin>>v>>p;
for(i=1;i<=v;i++) cin>>x[i];
for(i=1;i<=v;i++) d[i][i] = 0;
for(i=1;i<=v;i++)
for(j=i+1;j<=v;j++){
d[i][j] = d[i][j-1] + x[j] - x[(i+j)/2];
}
for(i=1;i<=p;i++)
for(j=1;j<=v;j++)
value[i][j] = INF;
for(i=1;i<=p;i++) value[i][i] = 0;
for(i=1;i<=v;i++) value[1][i] = d[1][i];
for(i=2;i<=p;i++)
for(j=i+1;j<=v;j++)
for(r=1;r<=j-i+1;r++){
if(value[i-1][j-r]+d[j-r+1][j] < value[i][j])
value[i][j] = value[i-1][j-r]+d[j-r+1][j];
}
cout<<value[p][v];
}