来来回回看了三四次,最后才把题意看懂了,三四次不是连续看。而是看了好几天。。。。
题意:
看输入,我以样例数据解释。
3 6 //3为城市个数,6为要坐飞机的次数。 2 130 150 //表示第1个城市到第2个城市的航班的价格,每两天一循环。例如,第一天130,第二天150,第三天130,第四天150 3 75 0 80 //第1个城市到第三个城市的航班价格,每3天一循环。 7 120 110 0 100 110 120 0 //第2个城市到第1个城市。 4 60 70 60 50 //第2个城市到第3个城市。 3 0 135 140 //第3个城市到第1个城市。 2 70 80 //第3个城市到第2个城市。 还有这题,有这句话: each day flying to a different city than the day before。意思应该是今天飞往的下一个地点不能是昨天的地点吧?但我测试数据的时候并没有这样的限制,结果一样还是过了。 2 3 1 1 1 1 Scenario #1 The best flight costs 3. ——————————————————————————————————————————————————————————————————————————————————————————————
思路:
定义dp[i][j]:第i天到达j城市的最小花费。
状态转移:dp[i][j] = min(dp[i][j], dp[i-1][p] + 第i-1天从p城市到 j 城市的费用);
一些细节的问题可以自己YY一下。
———————————————————————————————————————————————————————
AC代码:
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
using namespace std;
const int MAXN = 12;
const int MAXDAY = 35;
const int INF = 0x3f3f3f3f;
int price[MAXN][MAXN][MAXDAY], dp[1006][MAXN], day[MAXN][MAXN];
int n, k;
int main()
{
int cas = 0;
while(scanf("%d%d",&n, &k), n&&k)
{
for(int i = 0;i < n; i++)
{
for(int j = 0;j < n; j++)
{
int t;
if(i == j) continue;
scanf("%d", &t);
day[i][j] = t;
for(int p = 0;p < t; p++)
{
scanf("%d",&price[i][j][p]);
}
}
}
//
memset(dp, INF, sizeof(dp));
dp[0][0] = 0;
for(int i = 1;i <= k; i++) //day
{
for(int j = 0; j < n; j++) //dao da de chengshi
{
for(int p = 0; p < n; p++)//chufa de city
{
if(j != p)
{
int pri = price[p][j][ (i-1) % day[p][j] ];
//cout<<"pri = "<<pri<<endl;
if(pri == 0 || dp[i-1][p] == INF) continue;
dp[i][j] = min(dp[i][j], dp[i-1][p] + pri);
}
}
}
}
printf("Scenario #%d\n", ++cas);
if(dp[k][n-1] != INF)
printf("The best flight costs %d.\n",dp[k][n-1]);
else
printf("No flight possible.\n");
puts("");
}
return 0;
}