HDU 1227 Fast Food(经典DP)

来源:互联网 发布:萝卜花园软件 编辑:程序博客网 时间:2024/04/27 17:39

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=1227

题意:在n个饭店之间选m个攻击点,使每个饭店到他的供给点的总路程的值最小

思路:在i到j这几个饭店之间建设一个供给站,供给站必须建在i到j中间的一个才能保证值最小,dp[i][j]表示在前j个饭店之间建设i个供给点,当建第i个供给点的时候第i-1个供给点肯定已经建成

AC代码:

#include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <queue>#include <stack>#include <map>#include <cstring>#include <climits>#include <cmath>#include <cctype>const int inf = 0x7f7f7f7f;//2139062143typedef long long ll;using namespace std;int dp[40][210];int a[210];int cost(int x,int y)//在第x个饭店和第y个饭店之间建一个供给站的花费{    int t = (x + y) / 2;    int sum = 0;    for(int i=x; i<=y; i++)    {        sum += abs(a[i]-a[t]);    }    return sum;}int main(){    int n,m;    int cas = 0;    while(scanf("%d%d",&n,&m))    {        memset(dp,inf,sizeof(dp));        if(n + m == 0)            break;        for(int i=1; i<=n; i++)        {            scanf("%d",&a[i]);        }        for(int i=1; i<=n; i++)        {            dp[1][i]=  cost(1,i);        }        for(int i=2; i<=m; i++)        {            for(int j=1; j<=n; j++)            {                for(int k=i-1; k<j; k++)                {                    dp[i][j] = min(dp[i][j],dp[i-1][k] + cost(k+1,j));//在前个k个饭店建i-1个攻击点,最后一个供给点建在k+1到j之间                }            }        }        printf("Chain %d\n",++cas);        printf("Total distance sum = %d\n\n",dp[m][n]);    }    return 0;}


0 0
原创粉丝点击