【线性DP】Mobile Service SP703或洛谷P4046

链接

https://www.luogu.org/problemnew/show/P4046
https://www.luogu.org/problemnew/show/SP703

大意

一个公司有三个移动员,从一个点移到另一个点需要一定的代价,求满足所有要求的最小代价

思路

动态规划,按题意转移即可,我们可以利用滚动数组压缩空间

f [ i , x , y ] 表示完成了前 i 个请求,其中一个员工上一次位于 x ,这一次位于 y ,另外两个员工位于 u v 时的最小代价

f [ n o w ] [ v ] [ u ] = f [ n o w ] [ u ] [ v ] = m i n ( f [ n o w ] [ u ] [ v ] , f [ p r e ] [ u ] [ v ] + d [ x ] [ y ] )

f [ n o w ] [ x ] [ u ] = f [ n o w ] [ u ] [ x ] = m i n ( f [ n o w ] [ x ] [ u ] , f [ p r e ] [ u ] [ v ] + d [ v ] [ y ] )

f [ n o w ] [ x ] [ v ] = f [ n o w ] [ v ] [ x ] = m i n ( f [ n o w ] [ x ] [ v ] , f [ p r e ] [ u ] [ v ] + d [ u ] [ y ] ) ;

代码(单组数据)

#include<cstdio>
#include<cstring>
#include<algorithm>
#define r(i,a,b) for(register int i=a;i<=b;i++)
using namespace std;int n,m,a[1001],d[201][201],f[2][210][210],x,y,pre,now,ans=0x3f3f3f3f;
signed main()
{
    scanf("%d",&n);
    r(i,1,n) r(j,1,n) scanf("%d",&d[i][j]);
    while(scanf("%d",&a[++m])!=EOF);m--;
    memset(f,0x3f3f3f3f,sizeof(f));
    f[0][1][2]=d[3][a[1]];
    f[0][1][3]=d[2][a[1]];
    f[0][2][3]=d[1][a[1]];
    pre=1;now=0;
    r(i,2,m)
    {
        pre^=1;now^=1;
        memset(f[now],0x3f3f3f3f,sizeof(f[now]));
        x=a[~-i];y=a[i];
        r(u,1,n) if(u!=x)
         r(v,1,n)
        if(u!=v&&v!=x)
        {
            f[now][v][u]=f[now][u][v]=min(f[now][u][v],f[pre][u][v]+d[x][y]);
            f[now][x][u]=f[now][u][x]=min(f[now][x][u],f[pre][u][v]+d[v][y]);
            f[now][x][v]=f[now][v][x]=min(f[now][x][v],f[pre][u][v]+d[u][y]);
        }
    }
    r(i,1,n) r(j,1,n)
    if(i!=j&&i!=a[m]&&j!=a[m]) ans=min(ans,f[now][i][j]);
    printf("%d",ans);
}

代码(多组数据)

#include<cstdio>
#include<cstring>
#include<algorithm>
#define r(i,a,b) for(register int i=a;i<=b;i++)
using namespace std;int n,m,a[1001],d[201][201],f[2][210][210],x,y,pre,now,ans=0x3f3f3f3f,t;
signed main()
{
    scanf("%d",&t);
    while(t--)
    {
        memset(d,0,sizeof(d));
        scanf("%d%d",&n,&m);
        r(i,1,n) r(j,1,n) scanf("%d",&d[i][j]);
        r(i,1,m) scanf("%d",a+i);
        memset(f,0x3f3f3f3f,sizeof(f));
        f[0][1][2]=d[3][a[1]];
        f[0][1][3]=d[2][a[1]];
        f[0][2][3]=d[1][a[1]];
        pre=1;now=0;
        r(i,2,m)
        {
            pre^=1;now^=1;
            memset(f[now],0x3f3f3f3f,sizeof(f[now]));
            x=a[~-i];y=a[i];
            r(u,1,n) if(u!=x)
             r(v,1,n)
            if(u!=v&&v!=x)
            {
                f[now][v][u]=f[now][u][v]=min(f[now][u][v],f[pre][u][v]+d[x][y]);
                f[now][x][u]=f[now][u][x]=min(f[now][x][u],f[pre][u][v]+d[v][y]);
                f[now][x][v]=f[now][v][x]=min(f[now][x][v],f[pre][u][v]+d[u][y]);
            }
        }
        ans=0x3f3f3f3f;
        r(i,1,n) r(j,1,n)
        if(i!=j&&i!=a[m]&&j!=a[m]) ans=min(ans,f[now][i][j]);
        printf("%d\n",ans);
    }
}

猜你喜欢

转载自blog.csdn.net/xuxiayang/article/details/81807182
今日推荐