zoukankan      html  css  js  c++  java
  • zoj 3017 Extreme Gameplay

    http://acm.hust.edu.cn:8080/judge/contest/view.action?cid=11975#problem/D

    用f【i】【j】表示i号城堡到j号城堡所需要的魔法值。

    首先要用floyd算出任意两个城市之间到达所需要的最小魔法值。

    然后用t【i】【j】表示i号城堡从j-1号房间到达j号房间所需要的时间。

    用dp【k】【i】【j】表示当前魔法值为k到达i号城堡j号房间所需要的最短时间。

    如果已经知道了dp【k】【i】【j】那么我们就可以推出dp【k】【i】【j+1】,也可以推出dp【temp】【l】【j+1】(其中l是另一个城堡,temp是当期魔法值减去i号

    城堡到j号城堡所需要的魔法值。其中l!=i我们需要枚举l。

    本题

    #include<iostream>
    #include<string.h>
    #include<algorithm>
    #include<stdio.h>
    #define inf 0x7fffffff
    using namespace std;
    int dp[150][20][150];
    int f[20][20];
    int t[20][150];
    int main()
    {
       int test;
       int n,m,z;
       cin>>test;
       for(int p=1;p<=test;p++)
       {
           cin>>n>>m>>z;
           for(int i=1;i<=m;i++)
               for(int j=2;j<=n;j++)
                   cin>>t[i][j];
           for(int i=1;i<=m;i++)
               for(int j=1;j<=m;j++)
                   cin>>f[i][j];
           for(int k=1;k<=m;k++)
               for(int i=1;i<=m;i++)
                   for(int j=1;j<=m;j++)
                       if(i!=j)
                           f[i][j]=min(f[i][j],f[i][k]+f[k][j]);
           memset(dp,-1,sizeof(dp));
           dp[z][1][1]=0;
           for(int i=2;i<=m;i++)
           {
               int temp=z-f[1][i];
               if(temp>=0)
               {
                   dp[temp][i][1]=0;
               }
           }
           for(int j=1;j<n;j++)
           {
               for(int k=0;k<=z;k++)
               {
                   for(int i=1;i<=m;i++)
                   if(dp[k][i][j]!=-1)
                   {
                       if(dp[k][i][j+1]==-1||dp[k][i][j+1]>dp[k][i][j]+t[i][j+1])
                           dp[k][i][j+1]=dp[k][i][j]+t[i][j+1];
                       for(int l=1;l<=m;l++)
                           if(l!=i)
                           {
                               int temp=k-f[i][l];
                               if(temp>=0)
                               {
                                   int ans=dp[k][i][j]+t[l][j+1];
                                   if(dp[temp][l][j+1]==-1||dp[temp][l][j+1]>ans)
                                       dp[temp][l][j+1]=ans;
                               }
                           }
                   }
               }
           }
           int ans=inf;
           for(int i=1;i<=m;i++)
               for(int k=0;k<=z;k++)
               if(dp[k][i][n]!=-1)
                   ans=min(ans,dp[k][i][n]);
           cout<<ans<<endl;
       }
       return 0;
    }

    是属于那种知道当前状态去递推后一种状态的情况。

  • 相关阅读:
    worldWind发布1.3.2版本了
    XMLSerializer中数组对象的设定
    IE6+UTF8的一个怪异问题
    恢复ServU管理员密码方法
    asp.net中的窗体身份验证(不同的角色访问不同的目录)
    什么是 Landing Page?
    如何让排名更加稳定
    JS替换空格回车换行符
    外部调用ZBLOG文章的方法
    表单填写字母时大小写自动互转(CSS方式)
  • 原文地址:https://www.cnblogs.com/cs1003/p/2653403.html
Copyright © 2011-2022 走看看