UVA 590

题意:
好长的题看了好久= =
有 n 个城市,编号 1~N, Trisha要坐飞机旅行 k 天,每天到一个城市,最后一天要到 N 城市。
也就是起点是城市1,第 k 天要到达 N 城市。求 k 天旅行的最小花费。
每个城市到其他城市都有一个航班表,x 天为周期,循环,接下来 x 个数表示航班价格。

多组输入,每组第一行输入 n 和 k;输入 0 0结束。
接下来 n(n-1)行,表示每个城市到其他城市的航班表。
也就是说第 i 个 (n-1)行, 表示 城市 i 到其余(n-1)个城市的航班表。
航班表第一个数表示周期天数,接下来每天的价格。

例如:
3 6 (n ,k n个城市,k 天。往下共 3*2行)
2 130 150 (城市1到城市2的航班 2 天为一周期,第一天130,第二天150,第三天130..循环...)
3 75 0 80 (城市1到城市3的航班 3 天为一周期,第一天75,第二天没有航班,第三天80..)
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

解题:
d[i][j] 表示 第 i 天到达第 j 个城市的最小花费。
p[i][j][q] 表示从 i 城市到 j 城市的第 q 个价格(因为会循环所以轮到第 q 个);
那么 d[i][j] = min (d[i][j], d[i-1][k] + pri[k][j][q]);
就是 第 i 天到达第 j 个城市的最小花费等于
第 i-1 天到达第 k 个城市的花费加上 k 到 j 的花费与原来统计结果两者取小。
其中 j != k, 并且pri[k][j][q] != 0 (有航班可到达),d[i-1][k] != INF (到达过k城市);

#include <bits/stdc++.h>
#define ll long long
using namespace std;

const int INF = 0x3f3f3f3f;

int num[15][15], d[1010][15], pri[15][15][1010];

int main()
{
    int n, k, x, cas = 1;
    while (scanf ("%d%d", &n, &k) != EOF && (n || k)) {
        memset (pri, 0, sizeof (pri));
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j ++) {
                if (i == j) continue;
                scanf ("%d", &num[i][j]);
                for (int k = 1; k <= num[i][j]; k ++) {
                    scanf ("%d", &pri[i][j][k]);
                }
            }
        }
        memset (d, INF, sizeof (d));
        d[0][1] = 0;
        for (int i = 1; i <= k; i ++) {
            for (int j = 1; j <= n; j ++) {
                for (int k = 1; k <= n; k ++) {
                    if (j == k) continue;
                    int q = (i-1) % num[k][j] + 1;
                    if (pri[k][j][q] != 0 && d[i-1][k] != INF )
                        d[i][j] = min (d[i][j], d[i-1][k] + pri[k][j][q]);
                }
            }
        }
        printf ("Scenario #%d\n", cas++);
        if (d[k][n] != INF)
            printf ("The best flight costs %d.\n\n", d[k][n]);
        else printf ("No flight possible.\n\n");
    }
    return 0;
}
时间: 2024-07-30 13:45:44

UVA 590的相关文章

UVA 590 二十一 Always on the run

Always on the run Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit Status Practice UVA 590 Appoint description:  System Crawler  (2015-08-26) Description Screeching tires. Searching lights. Wailing sirens. Police cars eve

UVA - 590 Always on the run

有n个点,问第k天从1到n的最少花费(第0天在点1) 已知两两之间穿梭需要的花费 已知从x到y,第几天的花费是多少(每天花费都可能不同,为0代表该天不可走) 啊,就是这样 #include<iostream> #include<map> #include<string> #include<cstring> #include<cstdio> #include<cstdlib> #include<cmath> #include

UVA 590 Always on the run(DP)

Screeching tires. Searching lights. Wailing sirens. Police cars everywhere. Trisha Quickfinger did it again! Stealing the `Mona Lisa' had been more difficult than planned, but being the world's best art thief means expecting the unexpected. So here s

递推DP UVA 590 Always on the run

题目传送门 题意:题意难懂,就是一个小偷在m天内从城市1飞到城市n最小花费,输入的是每个城市飞到其他城市的航班. 分析:dp[i][j] 表示小偷第i天在城市j的最小花费.状态转移方程:dp[i][j] = min (dp[i-1][k] + cost[k][j][t%day]) t表示在t天时k飞往j的飞机的花费 收获: 代码: /************************************************ * Author :Running_Time * Created

小白书关于动态规划

10192 最长公共子序列 http://uva.onlinejudge.org/index.php?option=com_onlinejudge& Itemid=8&page=show_problem&category=114&problem=1133&mosmsg= Submission+received+with+ID+13297616 */ #include <cstdio> #include <string.h> #include&

UVA 562 Dividing coins --01背包的变形

01背包的变形. 先算出硬币面值的总和,然后此题变成求背包容量为V=sum/2时,能装的最多的硬币,然后将剩余的面值和它相减取一个绝对值就是最小的差值. 代码: #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; #define N 50007 int c[102],d

UVA 10341 Solve It

Problem F Solve It Input: standard input Output: standard output Time Limit: 1 second Memory Limit: 32 MB Solve the equation: p*e-x + q*sin(x) + r*cos(x) + s*tan(x) + t*x2 + u = 0 where 0 <= x <= 1. Input Input consists of multiple test cases and te

UVA 11014 - Make a Crystal(容斥原理)

UVA 11014 - Make a Crystal 题目链接 题意:给定一个NxNxN的正方体,求出最多能选几个整数点.使得随意两点PQ不会使PQO共线. 思路:利用容斥原理,设f(k)为点(x, y, z)三点都为k的倍数的点的个数(要扣掉一个原点O).那么全部点就是f(1),之后要去除掉共线的,就是扣掉f(2), f(3), f(5)..f(n).n为素数.由于这些素数中包括了合数的情况,而且这些点必定与f(1)除去这些点以外的点共线,所以扣掉.可是扣掉后会扣掉一些反复的.比方f(6)在f

[UVa] Palindromes(401)

UVA - 401 Palindromes Time Limit: 3000MS   Memory Limit: Unknown   64bit IO Format: %lld & %llu Submit Status Description A regular palindrome is a string of numbers or letters that is the same forward as backward. For example, the string "ABCDED