uva590(DP)

题目的意思就是小明要坐飞机去旅行..

他必须从第一个城市出发, 并且以最后一个城市做终点.

先是给出n,k代表城市数量和要旅行的天数.

接下去n *(n - 1)行.

第一个城市 ,飞到第二个城市 .

第一个城市 ,飞到第三个城市.

.....

第一个城市飞到第n个..

第二个城市飞到第一个..

......

每行的数据是有k种航班,k个分别是 第一天飞的花费,第二天飞的花费.第k + 1天的花费 就等于第一天的花费..如果是0,代表这一天不能飞这条线路.


要求求出完成旅行的最少花费,如果不能完成(就是无法在第k天到达第n座城市,,,或者出现所有情况都会有一天没有飞机可坐).


那么我们要用一个f 数组,f[ i ][ j ] 就表示第i天 ,在第j座城市的话,总花费.

那么它的最小值 就是 f[ i - 1] [ l ]  (l取不等于j的数 ,表示第i-1 ,在第l座城市的总花费) 加上这一天 l飞到 j的花费. 取所有这些l中最小的..

但是要注意一点,如果无法在第i - 1天到达l ,那么就不能加入比较.或着l到j在这一天没有航班,也不能加入比较..



#include<stdio.h>
#include<string.h>
const int N = 1005;
const int M = 15;
int flight[M][M][M * 2 + 1];
int fnum[M][M];
int f[N][M];
int n,k;
int main () {
	int cas = 1;
	while(scanf("%d%d",&n,&k) && n) {
		memset(f , 0 ,sizeof(f));
		memset(flight , 0 ,sizeof(flight));
		for (int i = 1 ; i <= n ;i++) {
			for (int j = 1; j <= n ;j++) {
				if (i == j)
					continue;
				scanf("%d",&fnum[i][j]);
				for (int t = 0; t < fnum[i][j] ;t++) {
					scanf("%d",&flight[i][j][t]);
				}
			}
		}
		int m;
		for (int i = 1 ; i <= k ;i++) {
			if(i == 1) {
				for (int j = 1 ; j <= n ;j++) {
					f[1][j] = flight[1][j][0] ;
				}
				continue;
			}
			for (int j = 1 ; j <= n ;j++) {
				m = 0x3f3f3f3f;
				for (int l = 1 ; l <= n ;l++) {
					if (j == l)
						continue;
					if (f[i - 1][l] && flight[l][j][(i - 1) %fnum[l][j]] && f[i - 1][l] + flight[l][j][(i - 1) % fnum[l][j]] < m)
						m = f[i - 1][l] + flight[l][j][(i - 1) % fnum[l][j]];
				}
				if(m != 0x3f3f3f3f)
					f[i][j] = m;
			}
		}
		if (f[k][n] != 0) {
			printf("Scenario #%d\nThe best flight costs %d.\n\n",cas++ ,f[k][n]);
		}
		else
			printf("Scenario #%d\nNo flight possible.\n\n",cas++);
	}
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值