NC229129. 游戏人生
描述
白正在玩的游戏到了boss阶段,该阶段一共有个回合,对于每个回合,由白先行动,然后boss再进行攻击。
每回合白可以选择下面一种方式进行操作:
1.普通攻击,对boss造成点伤害。
2.狂暴攻击,当自己生命值大于时,可以消耗点生命值对boss造成点伤害。
3.防御,本回合boss对你造成的点伤害变为(向下取整)。
经过攻略查询,现已知boss的初始生命值为,以及每个回合对玩家造成的伤害为。
游戏要求白必须在个回合内战胜boss(即在个回合的某个回合内使boss的生命值降为或者更低),并保证这个过程中白的生命值一直大于。
在保证通关游戏的前提下,请计算白的最少初始生命值。若无法通关游戏,则输出。
输入描述
第一行一个正整数,表示数据组数,对于每组数据:
第一行三个正整数,,,其中。
第二行一个正整数,。
接下来个正整数,表示第个回合boss对玩家造成的伤害,。
保证。
输出描述
对于每组数据,输出白通关需要的最少生命值,若无法通关,则输出。
示例1
输入:
1 5 1 1 3 1 1 1
输出:
5
C++ 解法, 执行用时: 153ms, 内存消耗: 2260K, 提交时间: 2021-11-13 10:46:16
#include<bits/stdc++.h> using namespace std; typedef long long ll; int i,j,k,t,n,m; ll hp,x,y,a[200500],sum,sb,res,tmp; priority_queue<ll> q; int main(){ cin.tie(0); cin>>t; while(t--){ cin>>hp>>x>>y>>n; for(i=1;i<=n;i++)cin>>a[i]; hp=(hp+x-1)/x;tmp=hp; if(2ll*n<hp){cout<<"-1\n";continue;} while(!q.empty())q.pop(); sb=sum=0;res=1e18; for(i=1;i<=n;i++){ if(q.size()*2+2>=hp){ res=min(res,1+sum+sb+(hp-(ll)q.size()-1)*y); } sum+=a[i]/2; sb+=(a[i]-a[i]/2); q.push(a[i]-a[i]/2); while((ll)q.size()*2>=hp&&q.top()>y||q.size()>=hp){ sb-=q.top();q.pop(); } } cout<<res<<'\n'; } }