题目大意
有n种技能,每秒使用h点生命,m点法力,造成d点伤害,技能使用时间可以是实数。你有hp点生命,m点法力,求最大造成的伤害及这时每种技能使用的时间。
解题思路
考虑造成单位伤害所需要的生命和法力,把这两个值投射到二维平面上,形成很多向量,可以发现选取一些向量,它们的和向量越靠近对角线,答案越大,可以证明组成答案的向量数不会超过两个,直接暴力枚举即可。
code
using namespace std;
int const mn=1000+9,inf=1e9+7;
int t,n,a[10];
LF hp,mp,h[mn],m[mn],d[mn],b[mn];
int main(){
freopen("terraria.in","r",stdin);
freopen("terraria.out","w",stdout);
scanf("%d",&t);
fo(cas,1,t){
scanf("%d%lf%lf",&n,&hp,&mp);
fo(i,1,n)scanf("%lf",&h[i]);
fo(i,1,n)scanf("%lf",&m[i]);
fo(i,1,n)scanf("%lf",&d[i]),h[i]/=d[i],m[i]/=d[i];
LF ans=0;
fo(i,1,n){
LF tmp=min(hp/h[i],mp/m[i]);
if(tmp>ans){
ans=tmp;
fo(j,1,a[0])b[a[j]]=0;
a[a[0]=1]=i;b[i]=tmp;
}
fo(j,i+1,n){
if(!(h[i]*m[j]-h[j]*m[i]))continue;
LF x=(hp*m[j]-mp*h[j])/(h[i]*m[j]-h[j]*m[i]),
y=(hp-x*h[i])/h[j];
if((x<0)||(y<0))continue;
if(x+y>ans){
ans=x+y;
fo(k,1,a[0])b[a[k]]=0;
a[0]=2;a[1]=i;a[2]=j;
b[i]=x;b[j]=y;
}
}
}
printf("%.10lf\n",ans);
fo(i,1,n)printf("%.10lf ",b[i]/d[i]);
printf("\n");
}
return 0;
}