poj 1160
令res[i][j]表示前i个邮局负责前j个村庄的最小值。
res[i][j]=res[i-1][k] + dist(k+1,j), (i<=j<=m,i-1<=k<j);
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int pos[301],res[35][301]; #define MAX 1234567890 int min(int a,int b) { return a < b ? a : b; } int dist(int i,int j) { int sum=0; while(i<j) { sum+=pos[j--]-pos[i++]; } return sum; } int work(int n,int m) { int i,j,k; for(j=1;j<=m;j++) res[1][j]=dist(1,j); for(i=2;i<=n;i++) for(j=i;j<=m;j++) { res[i][j]=MAX; for(k=i-1;k<j;k++) res[i][j]=min(res[i][j],res[i-1][k]+dist(k+1,j)); } return res[n][m]; } int main() { int i,m,n; while(scanf("%d %d",&m,&n)!=EOF) { memset(res,0,sizeof(res)); for(i=1;i<=m;i++) scanf("%d",&pos[i]); printf("%d\n",work(n,m)); } return 0; }