题目大意为小偷逃跑,有n个城市可以去,计划逃脱k天,问第k天到达目的地即n号城市的最小花费,主要是输入那部分比较不太好理解,每n-1行对应一个城市到达另外n-1个城市的信息,d表示循环节,之后d个整数表示每天的费用,0表示没有航班。
设状态dp(t,i)表示第t天在i号城市的最小花费,那么状态转移为dp(t,i)=min{dp[t-1][j]}(dp[t-1][j]!=-1 && cost[i][j][ t % d[i][j] ]!=0)。cost[i][j][ t % d[i][j] ]表示在第t天从i到j所需费用。
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
int dp[1010][11];
int cost[11][11][35];
int size[11][11];
int main()
{
int n,T,ca=1;
while(cin>>n>>T&&(n||T)){
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++){
if(i==j) continue;
int t;
cin>>t;
size[i][j]=t;
for(int k=0;k<t;k++) cin>>cost[i][j][k];
}
memset(dp,-1,sizeof(dp));
dp[0][1]=0;
for(int t=0;t<T;t++)
for(int i=1;i<=n;i++) if(dp[t][i]!=-1){
for(int j=1;j<=n;j++) if(i!=j){
int& a=dp[t+1][j];
int& b=cost[i][j][t%size[i][j]];
if(!b) continue;
if(a==-1) a=dp[t][i]+b;
else a=min(a,dp[t][i]+b);
}
}
cout<<"Scenario #"<<ca++<<endl;
if(dp[T][n]==-1) cout<<"No flight possible."<<endl;
else cout<<"The best flight costs "<<dp[T][n]<<"."<<endl;
cout<<endl;
}
return 0;
}