题解:游历的路线”
题解
游历的路线(lines.pas/cpp)
Time Limits: 1000 ms Memory Limits: 131072 KB Detailed Limits
题目的意思就是说,给你n个点,每个点可以到达其它所有的点,到达其它点需要花钱,每两点之间有一个周期,每两个点之间的花费成周期性的变化。我们要求的是从点1在第m天时到点n的最小花费,如果不能在第m天时到达点n,则无解,输出0。
这道题稍微想一下就可以想到动态规划,比赛时我想到了但没打出来,我们定义一个数组t[i][j],表示城市i到j的周期;一个数组w[i][j][k]表示城市i到j周期中第k个周期所需要的花费(如果是0则无法到达);一个变量c表示现在是周期中的第c个周期;f[i][j]第i天从城市1到j所需要的最小花费;用三个for循环,第一层枚举天数i,第二层枚举城市j,第三层枚举城市k,状态转移方程就是f[i][j]=min(f[i][j],f[i-1][k]+w[k][j][c]),结果就是f[m][n]。但这样还不够,因为有可能有写点在第i天的时候刚好不能到达其它的一个点,所以我们给f[i][j]的初始值全部附为-1,当f[i-1][k]=-1时,跳过这一次循环,因为这说明第i-1天无法从城市1到k,判断完这个后,如果f[i][j]=-1,直接f[i][j]=f[i-1][k]+w[k][j][c],因为f[i][j]=-1表示还没有走过,并不是不能到达,因为这之前已经判断过了,如果不能到达就已经跳出了循环,不会到这一步。还有给f[i][j]的初始值附为-1后,要再把f[0][1]=0,表示第0天到城市1用了0元,这样才能计算出正确答案,否则如果没有这个语句,f[0][1]=-1就表示第0天到城市1用了-1元,错误了。
附上代码:
1 #include<iostream>
2 #include<cstring>
3 #include<cstdio>
4 using namespace std;
5 int m,n,o;
6 int f[300][300];
7 int t[300][300];
8 int w[300][300][25];
9 void read();
10 void solve();
11 int main()
12 {
13 read();
14 solve();
15 printf("%d",f[m][n]);
16 return 0;
17 }
18 void solve()
19 {
20 for(int i=1;i<=m;i++)
21 for(int j=1;j<=n;j++)
22 for(int k=1;k<=n;k++)
23 {
24 if(j==k) continue;
25 int c=i;
26 if(c%t[k][j]!=0) c%=t[k][j];
27 else c=t[k][j];
28 if(w[k][j][c]==0) continue;
29 if(f[i-1][k]==-1) continue;
30 if(f[i][j]==-1) f[i][j]=f[i-1][k]+w[k][j][c];
31 f[i][j]=min(f[i][j],f[i-1][k]+w[k][j][c]);
32 }
33 }
34 void read()
35 {
36 scanf("%d%d",&n,&m);
37 for(int i=1;i<=n;i++)
38 for(int j=1;j<=n;j++)
39 {
40 if(i==j) continue;
41 scanf("%d",&t[i][j]);
42 for(int k=1;k<=t[i][j];k++)
43 scanf("%d",&w[i][j][k]);
44 }
45 memset(f,-1,sizeof(f));
46 f[0][1]=0;
47 }
by:ルオ・テンイの锦依卫
未经作者允许,禁止转载!