AcWing 274. 移动服务
原题链接
中等
作者:
帅
,
2021-03-23 11:00:13
,
所有人可见
,
阅读 379
题解:
这题是从当前状态往后状态只有三种情况, 所以是从后一个状态往前推。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e6+6;
int l, n;
int a[maxn];
int c[1005][1005];
int f[1005][205][205]; // 分别表示三个人在的位置 第一个也代表完成的问题数目
int main()
{
cin >> l >> n;
for(int i = 1; i <= l; i ++)
{
for(int j = 1 ; j <= l; j ++)
{
cin >> c[i][j];
}
}
for(int i = 1; i <= n; i ++)
{
cin >> a[i];
}
memset(f, 0x3f, sizeof f);
a[0] = 3; // 第一个人在3位置
f[0][1][2] = 0; // 第二个人在1 位置 第三个人在2位置
for(int i = 0; i < n; i ++)
for(int x = 1; x <= l; x ++)
for(int y = 1; y <= l; y ++)
{
int z = a[i]; // z这个人在a[i]这个位置
if(x == y || x == z || y == z) continue; // 如果位置有重叠 则不算
f[i+1][x][y] = min(f[i+1][x][y], f[i][x][y] + c[z][a[i+1]]); // z位置的人去修
f[i+1][z][y] = min(f[i+1][z][y], f[i][x][y] + c[x][a[i+1]]); // x位置的人去修
f[i+1][x][z] = min(f[i+1][x][z], f[i][x][y] + c[y][a[i+1]]); // y位置的人去修
}
int mini = 0x3f3f3f3f;
for(int x = 1; x <= l; x ++)
for(int y = 1; y <= l; y ++)
{
int z = a[n];
if(x == y || x == z || y == x) continue;
mini = min(mini, f[n][x][y]);
}
cout << mini << endl;
return 0;
}