codeforces 487a//Fight the Monster// Codeforces Round #278(Div. 1)
题意:打怪兽。可增加自己的属性,怎样在能打倒怪兽的情况下花费最少?
这题关键要找好二分的量。一开始我觉得,只要攻击到101,防御到100,就能必胜,于是我对自己的三个属性的和二分(0到201),内部三层循环(最多到不了200*200*200)。1秒内能过。不过发现如果生命值很便宜,防御很贵的话,买生命值合算。10100点生命值就能必赢,于是上界调为10100,超时。
后来就想,二分攻击(记为i)和防御(记为j)的和mid,内部二重循环列出i+j=mid的所有情况。再单独二分生命值k,如果ijk的组合能打倒怪兽,再缩小k的值,再判断。不过这样做的话最外层应该枚举而不是二分。复杂度是200*200*200*log(10000),上面那种做法是10000*10000*10000*log(10000)。
乱码:
//#pragma comment(linker,"/STACK:1024000000,1024000000") #include<iostream> #include<cstdio> #include<string> #include<cstring> #include<vector> #include<cmath> #include<queue> #include<stack> #include<map> #include<set> #include<algorithm> #include <stack> #include <list> using namespace std; const int SZ=1000010,INF=0x7FFFFFFF; typedef long long lon; const double EPS=1e-9; int main() { std::ios::sync_with_stdio(0); //freopen("d:\\1.txt","r",stdin); int hy,ay,dy,hm,am,dm,a,b,c; cin>>hy>>ay>>dy>>hm>>am>>dm>>a>>b>>c; int lo=0;int hi=201,res=INF; for(int mid=0;mid<201;++mid) { //int mid=(lo+hi)/2; bool ok=0; for(int i=0;i<=mid;++i) { //if(i>100)cout<<i<<endl; for(int j=0;j<=mid&&i+j<=mid;++j) { //if(mid>100)cout<<mid<<endl; //if(i==100&&j)cout<<j<<endl; int hc=0,ac=ay+i,dc=dy+j; int curcost=b*i+c*j; int mhurt=max(0,am-dc); int yhurt=max(0,ac-dm); if(mhurt==0&&yhurt!=0) { ok=1; res=min(res,curcost); //if(res==6289)cout<<i<<" "<<j<<" "<<k<<endl; } else if(mhurt&&yhurt) { int hlo=0,hhi=1e5+100; int oldcost=curcost; for(;hlo<hhi;) { int innerok=0; int hmid=(hlo+hhi)/2; int hc=hy+hmid; int coin=(hc%(am-dc)==0); int hit=hc/(am-dc); if(coin)--hit; int mend=hm/(ac-dm)+(hm%(ac-dm)!=0); if(hit>=mend) { curcost=oldcost+hmid*a; ok=1; innerok=1; res=min(res,curcost); //if(res==6289)cout<<i<<" "<<j<<" "<<k<<endl; } if(innerok)hhi=hmid; else hlo=hmid+1; } } } } //cout<<mid<<" "<<ok<<endl; if(ok)hi=mid; else lo=mid+1; } cout<<res<<endl; return 0; }
浙公网安备 33010602011771号