HDU 5859 Captain is coding

来源:互联网 发布:网络流行歌曲2017劲爆 编辑:程序博客网 时间:2024/06/01 16:00

有两场比赛同时开始,一共有N道题,第一场的结束时间为X,第二场的结束时间为Y,要求AK,初始能力值为W,刷一次板子可以使能力值提高Z,第i题要求能力值Ci,A了之后能力值会提高Di,且只属于一场比赛(必须在XY之前A掉),每单位时间只能A一道题或刷一次板子,求最短AK时间或输出无解。
0<N<=1000,0<X,Y<=1000000,0<Z<=1000,0<=W<=109,0<=Ci<=109,0<=Di<=1000

二分完成时间判是否可行.不妨设A的deadline比B的deadline短,对于一次判断内,由于总时间固定,两类任务完成的总时间固定,则可用来练习的时间也固定,首先找到可完成的收益最大的 A类任务,若找不到则在B里找,此时若B类的收益还不如去练习,而且练习时间有剩余的话,就先去练习.A类任务若能做则不需要考虑收益,因为要优先保证A的deadline,先练后练对最优解无影响.

和chk一起做的

看起来很有意思的题, btw,模拟工厂也很有意思

贪心+二分

#include <set>#include <ctime>#include <queue>#include <cstdio>#include <bitset>#include <cctype>#include <bitset>#include <cstdlib>#include <cassert>#include <cstring>#include <iostream>#include <algorithm>#define inf (1<<30)#define INF (1ll<<62)#define fi first#define se second#define rep(x,s,t) for(register int x=s,t_=t;x<t_;++x)#define per(x,s,t) for(register int x=t-1,s_=s;x>=s_;--x)#define travel(x) for(int I=last[x],to;I&&(to=e[I].to);I=e[I].nxt)#define prt(x) cout<<#x<<":"<<x<<" "#define prtn(x) cout<<#x<<":"<<x<<endl#define pb(x) push_back(x)#define hash asfmaljkg#define rank asfjhgskjf#define y1 asggnja#define y2 slfvmusing namespace std;typedef long long ll;typedef pair<int,int> ii;template<class T>void sc(T &x){    int f=1;char c;x=0;    while(c=getchar(),c<48)if(c=='-')f=-1;    do x=x*10+(c^48);    while(c=getchar(),c>47);    x*=f;}template<class T>void nt(T x){    if(!x)return;    nt(x/10);    putchar(x%10+'0');}template<class T>void pt(T x){    if(x<0)putchar('-'),x=-x;    if(!x)putchar('0');    else nt(x);}template<class T>void ptn(T x){    pt(x);putchar('\n');}template<class T>void pts(T x){    pt(x);putchar(' ');}template<class T>inline void Max(T &x,T y){if(x<y)x=y;}template<class T>inline void Min(T &x,T y){if(x>y)x=y;}int n,X,Y,Wp,Z;const int maxn=1006;struct node{    int c,d;    bool operator <(const node&a)const{        return d<a.d;    }}A[2][maxn];int cnt[2],Lim[2];bool cmp(node a,node b){    return a.c<b.c;}int fi,se,pre;void input(){    sc(n);sc(Lim[0]);sc(Lim[1]);sc(Wp);sc(Z);    cnt[0]=cnt[1]=0;    rep(i,0,n){        int c,d;char s[4];        sc(c);sc(d);scanf("%s",s);        if(s[0]=='A')A[0][cnt[0]++]=(node){c,d};        else A[1][cnt[1]++]=(node){c,d};    }    fi=Lim[0]>Lim[1]?0:1;    se=fi^1;}bool judge(){    int rem=Lim[fi]-n;    if(rem<0||cnt[se]>Lim[se])return false;    int top=0,tp=0;    priority_queue<node>Q;    ll tt=0,W=Wp;    while(tp<cnt[fi]&&A[fi][tp].c<=W){            Q.push(A[fi][tp]);            tp++;        }    while(top<cnt[se]){        if(A[se][top].c<=W){            W+=A[se][top].d;            top++;        }        else{            if(!Q.empty()&&rem){                node p=Q.top();                if(p.d>=Z){                    Q.pop();                    W+=p.d;                }                else{                    int tar=tp<cnt[fi]?min(A[se][top].c,A[fi][tp].c):A[se][top].c;                    int nd=1ll*(tar-W+Z-1)/Z;                    nd=min(nd,rem);                    rem-=nd;                    W+=1ll*Z*nd;                    tt+=nd-1;                }            }            else if(!Q.empty()){                node p=Q.top();Q.pop();                W+=p.d;            }            else if(rem){                int tar=tp<cnt[fi]?min(A[se][top].c,A[fi][tp].c):A[se][top].c;                int nd=1ll*(tar-W+Z-1)/Z;                nd=min(nd,rem);                rem-=nd;                W+=1ll*Z*nd;                tt+=nd-1;            }            else return false;        }        while(tp<cnt[fi]&&A[fi][tp].c<=W){            Q.push(A[fi][tp]);            tp++;        }        tt++;        if(tt>Lim[se])return false;    }    while(!Q.empty()){        node p=Q.top();Q.pop();        W+=p.d;    }    while(tp<cnt[fi]){        if(A[fi][tp].c<=W){            W+=A[fi][tp].d;            tp++;        }        else if(rem){            int nd=(A[fi][tp].c-W+Z-1)/Z;            nd=min(nd,rem);            rem-=nd;            W+=1ll*Z*nd;        }        else return false;    }    return true;}void solve(){    input();pre=cnt[fi];    sort(A[fi],A[fi]+cnt[fi],cmp);    sort(A[se],A[se]+cnt[se],cmp);    int a=Lim[fi],b=Lim[se];    int l=n,r=Lim[fi],res=-1;    while(l<=r){        int mid=l+r>>1;        Lim[fi]=min(a,mid);        Lim[se]=min(b,mid);        if(judge()){            res=mid;            r=mid-1;        }        else l=mid+1;    }    if(res==-1)puts("Poor Captain Chen");    else ptn(res);}int main(){//  freopen("pro.in","r",stdin);//  freopen("chk.out","w",stdout);    int cas;sc(cas);    int kas=0;    while(cas--){        ++kas;        solve();    }    return 0;}
0 0
原创粉丝点击