HDU1227:Fast Food

题目链接:Fast Food

题意:一条直线上有n个饭店,问建造k个原料厂(仍旧在商店位置)得到的最小距离

分析:见代码

//一条直线上有n个饭店,问建造k个原料厂(仍旧在商店位置)得到的最小距离
//首先预处理从i到j的最小距离,可以知道选的点必为(i+j)/2,所以用dis[i][j]记录距离
//dp[i][j]表示前j个建造了i个原料厂的最小距离, 
//状态转移:dp[i][j]从min(dp[i-1][m])(i-1<=m<=j-1)转移过来,因为
//需要建厂的位置可选在i~j,故有此转移方程,需要将dp[i][j]初始化为inf,并且先处理dp[1][i]=dis[1][i] 
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

int cas,n,k,loc[220],dis[220][220],dp[31][201];

int main()
{
    while(scanf("%d %d",&n,&k),n&&k)
    {
        for(int i=1;i<=n;++i) scanf("%d",loc+i);
        //若在i到j之间建原料站,则产生的距离dis[i][j] 
        for(int i=1;i<=n;++i)for(int j=1;j<=n;++j)
        {
            dis[i][j]=0;
            for(int p=i;p<=j;++p) dis[i][j]+=abs(loc[p]-loc[(i+j)>>1]);
        }
        for(int i=1;i<=n;++i) dp[1][i]=dis[1][i];
        for(int i=2;i<=k;++i)for(int j=i;j<=n;++j)
        {
            dp[i][j]=0x3f3f3f3f;
            for(int m=i-1;m<j;++m) 
            dp[i][j]=min(dp[i][j],dp[i-1][m]+dis[m+1][j]);
        }
        printf("Chain %d
Total distance sum = %d

",++cas,dp[k][n]);
    }
} 
View Code
原文地址:https://www.cnblogs.com/chendl111/p/5831756.html