FZU1005 Fast Food动态规划

博客详细介绍了FZU1005 Fast Food问题的动态规划解决方案,包括解题思路、AC代码以及中点仓库最优证明过程,讨论了如何通过动态规划优化问题求解,并指出在特定情况下仓库位置选择中点可达到距离和最小值。
摘要由CSDN通过智能技术生成

FZU1005 Fast Food

Time Limit: 1000 mSec Memory Limit : 32768 KB
题目链接

解题思路

第一反应是二分答案+贪心23333 后来还是考虑了动态规划
f[k][l][r]其中 k 代表仓库数量 lr 分别代表左右区间,所以首先想到的是动规方程
f[k][l][r]=f[j][l][i]+f[k-j][i+1][r][l,r]分为两个部分取最优解
后来想到其实每个仓库所控制的区间互不相关,所以原动态转移方程
其实等同于f[k][l][r]=f[k-1][l][i]+f[1][i+1][r]将左半区间的k-1个仓库和右边仅有1个仓库的结果相加 将转移方程优化为:f[k][r]=f[k-1][i]+g[i+1][r]
其中 g[l][r][l,r]中放置一个仓库的最小值 根据推导结果可知当仓库取中间点(l+r)/2时所有点到仓库的距离和最小

AC代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
#define MAX 0x3f3f3f3f
int  f[205][205], g[205][205], a[205];
int main()
{
    int n, m, i, j, , r, l, k, ans, t = 0, mid;
    int max1;
    while (scanf("%d%d", &n, &m) != EOF)
    {
        if (n == 0 && m == 0)break;
        ++t;
        memset(g, 0, sizeof(g));
        memset(f, 0, sizeof(f));
        for (i = 1; i <= n; i++)    
             scanf("%d", &a[i]);
        for (i = 1; i <= n; i++)
            for (j = i; j <= n; j++)
            {
                mid = (i + j) / 2;
                for (k = i; k <= j; k++) 
                  g[i][j]+=abs(a[k]-a[mid]);
            }
        for (j = 1; j <= n; j++) f[1][j] = g[1][j];
        for (k = 2; k <= m; k++)
            for (r = k; r <= n; r++)
            {
                f[k][r] = MAX;
                for (i = 1; i < j; i++)
                    f[k][r] = min(f[k][r], f[k - 1][i] + g[i + 1][r]);
            }
        printf("Chain %d\n", t);
        printf("Total distance sum = %d\n\n", f[m][n]);
    }
    return 0;
}

中点仓库最优证明过程

设数组a1,a2,a3...an 假设n点为仓库点 设此时距离总和为Sn,设n点左右剩余数字的个数分别为a,b
设a[n]与a[n-1]距离为kn 当仓库从 n 移到 n-1 时 Sn-1= Sn - a*kn+(b+1)*kn = Sn - (a-b-1)*kn
因为 kn>0且(a-b-1)单调递减 所以当(a-b-1)正好小于等于0 时 Sn 为最小的距离总和此时  中点为距离总和最小值     
所以mid= (1+n)/2
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值