【jzoj5105】【GDSOI2017】【魔兽争霸 x】【结论】

题目大意

有n种技能,每秒使用h点生命,m点法力,造成d点伤害,技能使用时间可以是实数。你有hp点生命,m点法力,求最大造成的伤害及这时每种技能使用的时间。

解题思路

考虑造成单位伤害所需要的生命和法力,把这两个值投射到二维平面上,形成很多向量,可以发现选取一些向量,它们的和向量越靠近对角线,答案越大,可以证明组成答案的向量数不会超过两个,直接暴力枚举即可。

code

#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define LF double
#define LL long long
#define ULL unsigned long long
#define fo(i,j,k) for(int i=j;i<=k;i++)
#define fd(i,j,k) for(int i=j;i>=k;i--)
#define fr(i,j,k) for(int i=begin[j][k];i;i=next[j][i])
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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值