典型动态规划之Always On the Run

来源:互联网 发布:软件工程技术 编辑:程序博客网 时间:2024/04/28 10:30

 

Always On the Run

Description

Screeching tires. Searching lights. Wailing sirens.Police cars everywhere. Trisha Quickfinger did it again! Stealing the `MonaLisa' had been more difficult than planned, but being the world's best artthief means expecting the unexpected. So here she is, the wrapped frame tuckedfirmly under her arm, running to catch the northbound metro toCharles-de-Gaulle airport. 
But even more important than actually stealing the painting is to shake off thepolice that will soon be following her. Trisha's plan is simple: for severaldays she will be flying from one city to another, making one flight per day.When she is reasonably sure that the police has lost her trail, she will fly toAtlanta and meet her `customer' (known only as Mr. P.) to deliver the painting. 

Her plan is complicated by the fact that nowadays, even when you are stealingexpensive art, you have to watch your spending budget. Trisha therefore wantsto spend the least money possible on her escape flights. This is not easy,since airlines prices and flight availability vary from day to day. The priceand availability of an airline connection depends on the two cities involvedand the day of travel. Every pair of cities has a `flight schedule' whichrepeats every few days. The length of the period may be different for each pairof cities and for each direction. 

Although Trisha is a good at stealing paintings, she easily gets confused whenbooking airline flights. This is where you come in. 

Input

The input contains the descriptions of several scenariosin which Trisha tries to escape. Every description starts with a linecontaining two integers n and k. n is the number of cities through whichTrisha's escape may take her, and k is the number of flights she will take. Thecities are numbered 1, 2, ..., n, where 1 is Paris, her starting point, and nis Atlanta, her final destination. The numbers will satisfy 2 <= n <= 10and 1 <= k <= 1000. 
Next you are given n(n - 1) flight schedules, one per line, describing theconnection between every possible pair of cities. The first n - 1 flightschedules correspond to the flights from city 1 to all other cities (2, 3, ...,n), the next n - 1 lines to those from city 2 to all others (1, 3, 4, ..., n),and so on. 

The description of the flight schedule itself starts with an integer d, thelength of the period in days, with 1 <= d <= 30. Following this are dnon-negative integers, representing the cost of the flight between the twocities on days 1, 2, ..., d. A cost of 0 means that there is no flight betweenthe two cities on that day. 

So, for example, the flight schedule "3 75 0 80" means that on thefirst day the flight costs 75, on the second day there is no flight, on thethird day it costs 80, and then the cycle repeats: on the fourth day the flightcosts 75, there is no flight on the fifth day, etc. 

The input is terminated by a scenario having n = k = 0. 

Output

For each scenarioin the input, first output the number of the scenario, as shown in the sampleoutput. If it is possible for Trisha to travel k days, starting in city 1, eachday flying to a different city than the day before, and finally (after k days)arriving in city n, then print "The best flight costs x.", where x isthe least amount that the k flights can cost. 

If it is not possible to travel in such a way, print "No flightpossible.". 

Print a blank line after each scenario. 

Sample Input

3 6

2 130 150

3 75 0 80

7 120 110 0 100 110 120 0

4 60 70 60 50

3 0 135 140

2 70 80

2 3

2 0 70

1 80

0 0

Sample Output

Scenario #1

The best flight costs 460.

 

Scenario #2

No flight possible.

 

 

题目意思解读:首先给出城市数和航班数,接下来的(n-1)行代表城市1到2……n的开销,其中第一个数是周期数,接下来为周期数的具体数值。

求解:求从城市1出发到城市n公用k趟航班的最小开销。

解题思路:

   很显然马上回想到用动态规划的思想来解题。在这里,我们用flightnum[i][j]表示城市i到j的航班数,用cost[i][j][k]表示从城市i到j的第k天的花销。value[i][j]表示从城市1到城市i花费j趟航班的最小开销。显然可以令value[1][0]=0或者value[1][1]=0(具体视你怎么安排value这个数组)。则动态规划的方程为:value[i][j]=min(value[k][j-1]+cost[k][i][j]),k=1,2…

i-1,i+1…n;这其中还要考虑到cost[k][i][j]为0即没有航班的情况和value[k][j-1]是否大于0的问题。

具体代码如下:

(还需要注意一点的是如果有最小航班的话,在最小航班数字之后有个英文的小数点。不然总是给你跳错)

#include<iostream>

#include<cmath>

using namespace std;

 

#define maxcity 15 //最大城市数

#define maxday 35 //大于31即可

#define maxk 1005 //最大航班数

int n,k;//n是城市数目,k是航班数

intflightnum[maxcity][maxcity];//flightnum[i][j]表示城市i到j的航班数

intcost[maxcity][maxcity][maxday];//cost[i][j][j]从城市i到j的第k天的开销

int value[maxcity][maxk];//value[i][j]表示从城市1到i花费j趟航班的开销

 

void dp();//用dp求解

int main()

{

    intnumcase=1;

    cin>>n>>k;

    while((n!=0)&&(k!=0))

    {

        for(inti=1;i<=n;i++)

        {

            for(intj=1;j<=n;j++)

            {

                if(i!=j)

                {

                    //i到i之间没有航班

                    cin>>flightnum[i][j];

                    for(ints=0;s<flightnum[i][j];s++)

                    {

                        //录入城市i到j的航班花销

                        cin>>cost[i][j][s];

                    }

                }

            }

        }

        cout<<"Scenario#"<<numcase<<endl;

        numcase+=1;

        dp();

        cin>>n>>k;

    }

    return0;

}

 

void dp()

{

    for(inti=0;i<=n;i++)

    {

        for(intj=0;j<=k;j++)

        {

            //清空

            value[i][j]=-1;

        }

    }

    value[1][0]=0;//显然不能从城市1到城市1用0趟航班

    for(inti=1;i<=k;i++)

    {

        //i为航班数

        inttoday;

        for(intj=1;j<=n;j++)

        {

            //j是城市

            intmin=-1;//最小值,也可以为min赋一个很大的整数,下面修改min的赋值,一样可以

            for(ints=1;s<=n;s++)

            {

                //城市j到j和value[s][i-1]=-1都得排除

                if(s==j|| value[s][i-1]<0)

                    continue;

                today=(i-1)%flightnum[s][j];

                //没有航班

                if(cost[s][j][today]==0)

                    continue;

                if(min<0)

                    min=value[s][i-1]+cost[s][j][today];

                if(min>value[s][i-1]+cost[s][j][today])

                    min=value[s][i-1]+cost[s][j][today];

            }

            value[j][i]=min;

        }

    }

    if(value[n][k]<0)

        cout<<"Noflight possible."<<endl;

    else

        cout<<"Thebest flight costs "<<value[n][k]<<"."<<endl;

    cout<<endl;

}

0 0