• (floyd+DP) zoj 1232


    Adventure of Super Mario

    Time Limit: 2 Seconds      Memory Limit: 65536 KB

    After rescuing the beautiful princess, Super Mario needs to find a way home -- with the princess of course :-) He's very familiar with the 'Super Mario World', so he doesn't need a map, he only needs the best route in order to save time.

    There are A Villages and B Castles in the world. Villages are numbered 1..A, and Castles are numbered A+1..A+B. Mario lives in Village 1, and the castle he starts from is numbered A+B. Also, there are two-way roads connecting them. Two places are connected by at most one road and a place never has a road connecting to itself. Mario has already measured the length of every road, but they don't want to walk all the time, since he walks one unit time for one unit distance(how slow!).

    Luckily, in the Castle where he saved the princess, Mario found a magic boot. If he wears it, he can super-run from one place to another IN NO TIME. (Don't worry about the princess, Mario has found a way to take her with him when super-running, but he wouldn't tell you :-P)

    Since there are traps in the Castles, Mario NEVER super-runs through a Castle. He always stops when there is a castle on the way. Also, he starts/stops super-runnings ONLY at Villages or Castles.

    Unfortunately, the magic boot is too old, so he cannot use it to cover more than L kilometers at a time, and he cannot use more than K times in total. When he comes back home, he can have it repaired and make it usable again.


    Input

    The first line in the input contains a single integer T, indicating the number of test cases. (1<=T<=20) Each test case begins with five integers A, B, M, L and K -- the number of Villages, the number of Castles(1<=A,B<=50), the number of roads, the maximal distance that can be covered at a time(1<=L<=500), and the number of times the boot can be used. (0<=K<=10) The next M lines each contains three integers Xi, Yi, Li. That means there is a road connecting place Xi and Yi. The distance is Li, so the walk time is also Li. (1<=Li<=100)


    Output

    For each test case in the input print a line containing a single integer indicating the minimal time needed to go home with the beautiful princess. It's guaranteed that Super Mario can always go home.


    Sample Input

    1
    4 2 6 9 1
    4 6 1
    5 6 10
    4 5 5
    3 5 4
    2 3 4
    1 2 3


    Sample Output

    9

    题意:

    题目意思很简单:
    有A个村子和B个城堡,村子标号是1~A,城堡标号是A+1~B。马里奥现在位于城堡B,他要带公主回到村子1,他有一双靴子,穿上之后可以不用时间就能从一个地方飞到另外一个地方,但是穿着靴子不能穿过城堡,穿靴子的次数也不能超过 K 次,一次不能超过 L km。求从 B 到 1 所用的最短时间。

    逆向思维

    dp[i][j]表示 从1 到i用了j次靴子的最小花费

    目标状态 dp[n][k]

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<cstdlib>
    #define INF 100000000
    using namespace std;
    int a,b,m,l,k,n;
    bool vis[105][105];
    int dist[105][105],dp[105][105];
    void floyd()
    {
        for(int k=1;k<=n;k++)
        {
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=n;j++)
                {
                    if(dist[i][j]>dist[i][k]+dist[k][j])
                    {
                        dist[i][j]=dist[i][k]+dist[k][j];
                        if(k<=a&&dist[i][j]<=l)
                            vis[i][j]=vis[j][i]=1;
                    }
                }
            }
        }
    }
    int main()
    {
        int tt;
        scanf("%d",&tt);
        while(tt--)
        {
            memset(vis,0,sizeof(vis));
            scanf("%d%d%d%d%d",&a,&b,&m,&l,&k);
            n=a+b;
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=n;j++)
                    dist[i][j]=INF,dp[i][j]=INF;
                dist[i][i]=0;
            }
            for(int i=1;i<=m;i++)
            {
                int x,y,z;
                scanf("%d%d%d",&x,&y,&z);
                dist[x][y]=dist[y][x]=z;
                if(z<=l)
                    vis[x][y]=vis[y][x]=1;
            }
            floyd();
            for(int i=1;i<=n;i++)
                dp[i][0]=dist[1][i];
            for(int i=0;i<=k;i++)
                dp[1][k]=0;
            for(int i=2;i<=n;i++)
            {
                int minn=INF;
                for(int j=1;j<=k;j++)
                {
                    for(int t=1;t<i;t++)
                    {
                        if(vis[t][i])
                            minn=min(minn,min(dp[t][j-1],dp[t][j]+dist[t][i]));
                        else
                            minn=min(minn,dp[t][j]+dist[t][i]);
                    }
                    dp[i][j]=minn;
                }
            }
            printf("%d
    ",dp[n][k]);
        }
        return 0;
    }
    

      

  • 相关阅读:
    Android学习笔记——启动Activity及Activity生命周期
    TransposonPSI——转座子分析的入门自学
    关于 GraPhlAn 的孤独自学
    Javascript 正则表达式 子表达式
    关于set,list,map的理解
    js关于日期的操作
    JDBC和JTA事务区别
    远程调试本地服务或程序
    Fragment的数据传递
    记录自己的第一篇博客
  • 原文地址:https://www.cnblogs.com/water-full/p/4513786.html
Copyright © 2020-2023  润新知