甲开始时在 1 1 1号城市,要在第 m m m天恰好到达 n n n号城市,既不能早去,也不能晚去,也不能在到达一个城市后停留,每个城市到其他城市都有一个马车乘坐周期表,表示每天这两个城市间马车使用费用,也可能某一天两城市无法通过马车直接到达,问最少的费用能使得甲能在第 m m m恰好到达的是多少,不存在这样的路线输出0。
n < = 100 , m < = 200 , 周 期 T < = 20 , 单 天 马 车 使 用 费 用 < = 5000 n <= 100, m <= 200, 周期T <= 20, 单天马车使用费用 <= 5000 n<=100,m<=200,周期T<=20,单天马车使用费用<=5000
令 d p i , j dp_{i,j} dpi,j表示第 i i i天甲到了 j j j号城市的最小花费。
则显然
d p 0 , 1 = 0 dp_{0,1}=0 dp0,1=0
d p i , j = m i n ( d p i , j , d p i − 1 , k + c o s t k , j , i ) dp_{i,j}=min(dp_{i,j},dp_{i-1,k}+cost_{k,j,i}) dpi,j=min(dpi,j,dpi−1,k+costk,j,i)
c o s t k , j , i cost_{k,j,i} costk,j,i为 k k k号城市到 j j j号在第 i i i天的马车使用费用,这个是已知的
时间复杂度: O ( m ∗ n 2 ) O(m*n^2) O(m∗n2)
#include
#include
#include
#include
#include
#include
#define inf 0x3f3f3f3f
#define N 105
using namespace std;
int dp[2*N][N], a[N][N][25], cnt[N][N], n, m;
int main()
{
freopen("lines.in", "r", stdin);
freopen("lines.out", "w", stdout);
scanf("%d %d", &n, &m);
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
if (i != j)
{
scanf("%d", &cnt[i][j]);
for (int k = 1; k <= cnt[i][j]; k++)
{
scanf("%d", &a[i][j][k % cnt[i][j]]);
if (!a[i][j][k % cnt[i][j]]) a[i][j][k % cnt[i][j]] = inf;
}
}
for (int i = 0; i <= m; i++)
for (int j = 1; j <= n; j++) dp[i][j] = inf;
dp[0][1] = 0;
for (int i = 1; i <= m; i++)
for (int j = 1; j <= n; j++)
for (int k = 1; k <= n; k++)
if (j != k) dp[i][j] = min(dp[i][j], dp[i - 1][k] + a[k][j][i % cnt[k][j]]);
if (dp[m][n] != inf) printf("%d\n", dp[m][n]); else printf("%d\n", 0);
return 0;
}