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;
}

 

posted @ 2018-09-17 15:56  degvx  阅读(149)  评论(0)    收藏  举报