2236-Rabbit Plays Games!
解法
二人の場合を考える
さらに自分はかならず先制攻撃と見なす.
1:倒すまでの時間t1 受けるダメージ a1
2:倒すまでの時間t2 受けるダメージ a2
1→2の順で倒す場合
(t1-1)a1+(t1+t2-1)a2
2→1の順で倒す場合
(t2-1)a2+(t1+t2-1)a1
1→2が2→1よりも良くなる条件を調べる
(t1-1)a1+(t1+t2-1)a2 >= (t2-1)a2+(t1+t2-1)a1
t1*a1-a1-a2+a2*t1+a2*t2 >= t2*a2-a2-a1+a1*t1+a1*t2
a2*t1 >= a1*t2
t1/a1 >= t2/a2
a1/t1<=a2/t2
a1*t2<=a2*t1
この順番に貪欲に倒していく
実装(C++)
#include <algorithm> #include <iostream> #include <vector> using namespace std; typedef long long lli; struct Enemy{ lli time,attack; }; bool operator<(const Enemy &a,const Enemy &b){ return b.attack*a.time<b.time*a.attack; } lli n; lli h,a,d,s; lli mh,ma,md,ms; vector<Enemy> e; lli calc(lli a,lli d){ return max<lli>(a-d,0); } lli init; int main() { cin>>n; cin>>mh>>ma>>md>>ms; init=mh; for(lli i=0;i<n;i++){ cin>>h>>a>>d>>s; if(calc(ma,d)==0){//相手を倒せない if(calc(a,md)==0){ continue;//こいつは無害 }else{ cout<<-1<<endl; return 0; } } e.push_back((Enemy){(h+calc(ma,d)-1)/calc(ma,d),calc(a,md)}); if(s>ms){ mh-=calc(a,md); } } stable_sort(e.begin(),e.end()); lli now=0; for(lli i=0;i<(lli)e.size();i++){ mh-=e[i].attack*(e[i].time-1+now); if(mh<0)break; now+=e[i].time; } if(mh<=0)mh=-1;else mh=init-mh; cout<<mh<<endl; return 0; }