• 《算法竞赛进阶指南》0x51线性DP 移动服务


    题目链接:https://www.acwing.com/problem/content/276/

    题目给出m个地点,n个任务,每两个地点之间有距离,有三个服务员,初始时刻服务员在1,2,3位置,每个服务必须且只有一个人到指定的地点,问完成这些服务的最小移动距离之和,决策集合是所有完成了i个任务并且另外两个人在x,y位置的方案,属性是距离之和的最小值,在DP中有两种常见的更新方式,分别是通过依赖的状态来更新当前的状态和通过当前的状态去更新以来的状态

    本问题中,任务完成之后就会有一个人在任务i指定的地点,自由度变为3,用当前状态去更新依赖的状态的话只有三条出边,容易更新。从(x,y,p[i])点移动的话,只会是x,y,z三个人中的一个进行了移动。

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int maxn = 1010;
    const int maxm = 210;
    int p[maxn];
    int w[maxm][maxm];
    int f[maxn][maxm][maxm];
    int n,m;
    int main(){
        cin>>m>>n;
        for(int i=1;i<=m;i++)
            for(int j=1;j<=m;j++)
                scanf("%d",&w[i][j]);
        
        for(int i=1;i<=n;i++)scanf("%d",&p[i]);
        memset(f,0x3f,sizeof(f));
        p[0]=3;
        f[0][1][2]=0;
        for(int i=0;i<n;i++){
            for(int x=1;x<=m;x++){
                for(int y=1;y<=m;y++){
                    int z=p[i],v=p[i+1];
                    if(x==y || y==z || x==z)continue;
                    f[i+1][x][y]=min(f[i+1][x][y],f[i][x][y]+w[z][v]);
                    f[i+1][y][z]=min(f[i+1][y][z],f[i][x][y]+w[x][v]);
                    f[i+1][x][z]=min(f[i+1][x][z],f[i][x][y]+w[y][v]);
                }
            }
        }
        
        int ans = 0x3f3f3f3f;
        for(int x=1;x<=m;x++)
            for(int y=1;y<=m;y++){
                int z=p[n];
                if(x==y || x==z || y==z)continue;
                ans=min(ans,f[n][x][y]);
            }
        
        cout<<ans<<endl; 
    }
  • 相关阅读:
    性能测试概念
    接口测试概念
    SQL多表查询
    手机App测试概念
    App测试页面滑动
    自动化测试概念
    Monkey 命令
    Tomcat+JDK安装和配置
    Linux系统FTP安装、安装和使用
    Web测试方法(一)
  • 原文地址:https://www.cnblogs.com/randy-lo/p/13388098.html
Copyright © 2020-2023  润新知