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;

}

你可能感兴趣的:(poj)