链接:https://www.nowcoder.com/acm/contest/113/D
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
有a种武器,b种属性,和c种怪物。对于第k种怪物,给出武器i和属性j的搭配在一个单位时间内对其造成的伤害h
k,
i,j。已知一开始使用武器i,需要时间x
i,使用属性i,需要时间y
i。然后从武器i直接切换成武器j,需要时间f
i,j,从属性i直接切换成属性j需要时间g
i,j。有一个长度为n的怪物序列,给出怪物i的血量w
i和种类t
i,在打怪物的时候可以随意切换武器和属性,问按顺序打死所有怪物(使得血量<=0)至少需要多少时间。
输入描述:
给出四个整数a,b,c,n (1 <= a,b,n <= 100, 1 <= c <= 20) 接下来一行给出a个数字表示xi (1 <= xi <= 1e5) 接下来一行给出b个数字表示yi (1 <= yi <= 1e5) 接下来a行每行a个整数,表示fi,j (fi,i = 0, 当i!=j时,1 <= fi,j <= 1e3) 接下来b行每行b个整数,表示gi,j (gi,i = 0, 当i!=j时,1 <= gi,j <= 1e3) 接下来c个矩阵,每个矩阵有a行,每行b个整数,表示hk,i,j (1 <= hk,i,j <= 1e4) 接下来一行读入n个整数表示wi (1 <= wi <= 1e8) 接下来一行读入n个整数表示ti (1 <= ti <= c)
输出描述:
输出一个整数表示答案。
示例1
题解:设状态为d[i][j][k],表示处理完第i只怪,武器是j,属性是k的最短时间。武器/属性的切换只需在打每只怪之前考虑。转移的时候,分别考虑武器,属性的转换即可。 由于武器/属性的转换是一个有向图,间接切换可能比直接切换更优,所以一开始要跑Floyd求最短路。
#include<bits/stdc++.h> using namespace std; const int MAX=1e5+10; const int MOD=1e9+7; const double PI=acos(-1.0); typedef long long ll; ll x[200],y[200]; ll f[200][200],g[200][200]; ll h[30][200][200]; ll w[200],t[200]; ll d[101][101][101]; void Floyd(ll p[][200],int n) { for(int k=1;k<=n;k++) { for(int j=1;j<=n;j++) { for(int i=1;i<=n;i++)p[i][j]=min(p[i][j],p[i][k]+p[k][j]); } } } int main() { int a,b,c,n; cin>>a>>b>>c>>n; for(int i=1;i<=a;i++)scanf("%lld",&x[i]); for(int i=1;i<=b;i++)scanf("%lld",&y[i]); for(int i=1;i<=a;i++) for(int j=1;j<=a;j++)scanf("%lld",&f[i][j]); for(int i=1;i<=b;i++) for(int j=1;j<=b;j++)scanf("%lld",&g[i][j]); for(int i=1;i<=c;i++) for(int j=1;j<=a;j++) for(int k=1;k<=b;k++)scanf("%lld",&h[i][j][k]); Floyd(f,a); Floyd(g,b); for(int i=1;i<=n;i++)scanf("%lld",&w[i]); for(int i=1;i<=n;i++)scanf("%lld",&t[i]); memset(d,63,sizeof d); for(int i=1;i<=a;i++) for(int j=1;j<=b;j++)d[0][i][j]=x[i]+y[j]; for(int i=1;i<=n;i++) { for(int j=1;j<=a;j++) for(int k=1;k<=b;k++) for(int p=1;p<=a;p++)d[i][j][k]=min(d[i][j][k],d[i-1][p][k]+f[p][j]); for(int j=1;j<=a;j++) for(int k=1;k<=b;k++) for(int p=1;p<=b;p++)d[i][j][k]=min(d[i][j][k],d[i][j][p]+g[p][k]); for(int j=1;j<=a;j++) for(int k=1;k<=b;k++)d[i][j][k]+=(w[i]+h[t[i]][j][k]-1)/h[t[i]][j][k]; } ll ans=6e18; for(int i=1;i<=a;i++) for(int j=1;j<=b;j++)ans=min(ans,d[n][i][j]); cout<<ans<<endl; return 0; }