[题解]SP703 SERVICE - Mobile Service_Done

本文介绍了一种使用动态规划解决三个员工在不同地点完成任务的最小成本问题的方法。通过定义状态F[i][j][k]来表示完成任务i后的最小代价,其中一名员工在任务地点,另外两名员工分别在j和k地点。文章详细阐述了状态转移方程,通过迭代计算出所有可能的任务分配情况,最终找到总成本最低的方案。

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

设计状态F[i][j][k]代表完成任务i后,有一个员工在地点P[i],其他两人分别在j和k两地。所需要的最小代价。

转移的方式:

分别考虑派遣i,j,k三人前往下一个需求地点,并更新状态。

#include <iostream>
#include <stdio.h>
#include <string.h>
#define re register
#define GC getchar()
#define Clean(X,K) memset(X,K,sizeof(X))
#include <iostream>
#define Max(A,B) ((A)>(B)?(A):(B))
#define Min(A,B) ((A)<(B)?(A):(B))
using namespace std ;
int Qread () {
    int X = 0 ;
    char C = GC ;
    while (C > '9' || C < '0') C = GC ;
    while (C >='0' && C <='9') {
        X = X * 10 + C - '0' ;
        C = GC ;
    }
    return X ;
}
const int Maxl = 205 , Maxn = 1005 ,INF = 20021020 << 2;
int C[Maxl][Maxn] , N , L , Times , Q[Maxn] = {1}, F[Maxn][Maxl][Maxl];
int main () {
//    freopen ("SP703.in" , "r" , stdin) ;
    Times = Qread () ;
    while (Times -- ) {
        Clean (F , 0) ;
        L = Qread () , N = Qread () ;
        for (re int i = 1 ; i <= L; ++ i) for (re int j = 1 ; j <= L; ++ j) C[i][j] = Qread () ;
        for (re int i = 1 ; i <= N; ++ i) Q[i] = Qread () ;
        Clean (F , 0x3f) ;
        F[0][2][3] = 0 ;
        for (re int i = 0 ; i < N; ++ i) {
            for (re int j = 1 ; j <= L ; ++ j) {
                for (re int k = 1 ; k <= L; ++ k) {
                    if (Q[i] == j || Q[i] == k || j == k) continue ;
                    F[i + 1][j][k] = Min (F[i + 1][j][k] ,F[i][j][k] +  C[Q[i]][Q[i + 1]]) ;
                    F[i + 1][Q[i]][k] = Min (F[i + 1][Q[i]][k] , F[i][j][k] + C[j][Q[i + 1]]) ;
                    F[i + 1][j][Q[i]] = Min (F[i + 1][j][Q[i]] , F[i][j][k] + C[k][Q[i + 1]]) ;
                }
            }
        }
        int Ans = INF ;
        for (re int i = 1 ; i <= L ; ++ i) {
            for (re int j = 1 ; j <= L; ++ j) {
                Ans = Min (Ans , F[N][i][j]) ;
            }
        }
        printf ("%d\n" , Ans) ;
    }
    fclose (stdin) , fclose (stdout) ;
    return 0 ;
}

转载于:https://www.cnblogs.com/bj2002/p/10683010.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值