题意:给定n个城市,k次航班,接下来输入n * (n -1)行,
表示第i个城市和其他城市的航班,0表示当日无航班,航班形成周期。
要求出正好k次航班,从城市1到城市n,最少需要的钱。
思路:dp, dp[k][i] 表示经过k次航班的最小花费,到达哪个城市。
i代表时间,j表示起点城市,k表示终点城市,k表示第k次航班。
那么当次航班的时间为 now = i % edge[j][k].day;
价钱为 dp[i-1][j] + edge[j][k].cost[now]
表示第i个城市和其他城市的航班,0表示当日无航班,航班形成周期。
要求出正好k次航班,从城市1到城市n,最少需要的钱。
思路:dp, dp[k][i] 表示经过k次航班的最小花费,到达哪个城市。
i代表时间,j表示起点城市,k表示终点城市,k表示第k次航班。
那么当次航班的时间为 now = i % edge[j][k].day;
价钱为 dp[i-1][j] + edge[j][k].cost[now]
状态转移方程为 dp[i][k] = min(dp[i][k],dp[i-1][j] + edge[j][k].cost[now]);
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int INF = 0x3f3f3f3f;
struct Edge {
int day;
int cost[35];
}edge[15][15];
int dp[1005][15];
int n,m;
int main() {
int day,cost,cas = 1,flag = 0;
while(scanf("%d%d",&n,&m) != EOF && (n || m)) {
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++) {
if(i == j)
continue;
scanf("%d",&day);
edge[i][j].day = day;
for(int k = 1; k <= day; k++) {
scanf("%d",&cost);
edge[i][j].cost[k] = cost;
}
}
memset(dp,INF,sizeof(dp));
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) {
int now = i % edge[j][k].day;
if(now == 0) {
now = edge[j][k].day;
}
if(edge[j][k].cost[now]) {
dp[i][k] = min(dp[i][k],dp[i-1][j] + edge[j][k].cost[now]);
}
}
}
}
}
printf("Scenario #%d\n",cas++);
if(dp[m][n] == INF) {
printf("No flight possible.\n");
}else {
printf("The best flight costs %d.\n",dp[m][n]);
}
printf("\n");
}
return 0;
}