UVA - 662

本文介绍了一个使用动态规划解决餐厅配送问题的算法实现。通过定义状态转移方程,该算法能够找到K个配送点的最佳位置,使得所有配送路径的总距离最小。文章详细展示了递归求解过程,并提供了完整的C++代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstdlib>
using namespace std;
#define INF 1000000000
const int maxn = 202;
const int maxk = 31;
int d[maxk][maxn],n,K,dist[maxn],sum[maxn][maxn];//到第i个已经选完前j个
bool vis[maxk][maxn];

int dp(int i,int j){
if(vis[i][j]) return d[i][j];
vis[i][j]=1;

if(i==K-1){
     return d[i][j]=sum[j+1][n];
}
for(int l=j+1;n-l>=K-i-1;l++){
     int num=dp(i+1,l)+sum[j+1][l];
     d[i][j]= (l==j+1 ? num:min(d[i][j],num));
}
return d[i][j];
}
void print_ans(int i,int j){
     if(i==K-1){
         if(j+1<n)  printf("Depot %d at restaurant %d serves restaurants %d to %d\n",i+1,((n+j+1)>>1),j+1,n);
         else       printf("Depot %d at restaurant %d serves restaurant %d\n",i+1,((n+j+1)>>1),j+1);
         return ;
     }
     for(int l=j+1;n-l>=K-i-1;l++){
        int num=d[i+1][l]+sum[j+1][l];
        if(d[i][j]==num){
             if(j+1<l) printf("Depot %d at restaurant %d serves restaurants %d to %d\n",i+1,((l+j+1)>>1),j+1,l);
             else      printf("Depot %d at restaurant %d serves restaurant %d\n",i+1,((l+j+1)>>1),j+1);
             print_ans(i+1,l);
             break;
        }
     }
}
int main()
{
    int kase=1;
    while(scanf("%d %d",&n,&K)==2){
         if(!n&&!K) break;
         for(int i=1;i<=n;i++) scanf("%d",&dist[i]);
         for(int i=1;i<=n;i++)
           for(int j=i;j<=n;j++){
            int zhong = (i+j)>>1;
            sum[i][j]=0;
            for(int k=i;k<=j;k++) sum[i][j]+=abs(dist[k]-dist[zhong]);
         }
         memset(vis,false,sizeof(vis));
         int Sum = dp(0,0);
         printf("Chain %d\n",kase++);
         print_ans(0,0);
         printf("Total distance sum = %d\n\n",Sum);
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值