首页 > 代码库 > hdu 1277 Fast Food (dp)

hdu 1277 Fast Food (dp)

题目大意:

一条街上有很多个餐厅,现在要在n个餐厅中选取m个作为仓库。

使得其他的餐厅到这些仓库的距离的和最小。


思路分析:

状态方程: dp [i] [j]  表示  前 j 个餐厅已经建了 i 个仓库。

转移方程: dp[i] [j] = min ( dp[i-1] [k]  + cost[k+1][j] ) ...cost[ p ][ q ] 表示在p q 之间建立一个仓库的最小花费。


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

int dp[40][300];
int cost[300][300];
int pos[300];
int Abs(int x)
{
    return x>0?x:-x;
}
int main()
{
    int n,m,cas=1;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        if(n==0 && m==0)break;

        for(int i=1;i<=n;i++)
            scanf("%d",&pos[i]);

        memset(cost,0,sizeof cost);
        for(int i=1;i<=n;i++)
        {
            for(int j=i;j<=n;j++)
            {
                for(int k=i;k<=j;k++)
                {
                    cost[i][j]+=Abs(pos[k]-pos[(i+j)>>1]);
                }
            }
        }

        memset(dp,0x3f,sizeof dp);

        for(int i=1;i<=m;i++)dp[i][i]=0;
        for(int i=1;i<=n;i++)dp[1][i]=cost[1][i];//初始化
        for(int i=2;i<=m;i++)//已经初始化了 i == 1 的情况
        {
            for(int j=1;j<=n;j++)
            {
                for(int k=i-1;k<=j;k++)//从 i-1 开始
                {
                    dp[i][j]=min(dp[i][j],dp[i-1][k]+cost[k+1][j]);
                }
            }
        }

        printf("Chain %d\nTotal distance sum = %d\n\n",cas++,dp[m][n]);
    }
    return 0;
}