hdu 3433 A Task Process(二分答案+dp)

来源:互联网 发布:网络语不腻是什么意思 编辑:程序博客网 时间:2024/06/08 07:56

题意:给你x个A任务,y个B任务,然后有n个工人,每个工人完成A任务的时间为ai,完成B任务的时间为bi,几个工人可以同时开工,问你最少需要多少时间,能够完成所有任务。


感觉是dp,dp[i][x][y]表示到第i个工人位置做了x个A工作y个B工作需要的最少时间,但是这样的状态是O(nxy),转移是O(xy),时间上肯定超时。
于是这题需要换个姿势,就是先二分答案,二分出来最少的时间,然后判断能否在这个时间内做x个A任务和y个B任务,这又要怎么判断呢,如果状态像前面的一样dp[i][x][y]这样的话,仅仅用来表示能否有点浪费,因为它还能直接算出时间,所以我们应该换个方法,用dp[i][x]表示到第i个人,做了x个A任务,最多能做多少个B任务,这样就很好判断了,只要最后dp[n][x]y就是可行。


代码:

#include <map>#include <set>#include <stack>#include <queue>#include <cmath>#include <string>#include <vector>#include <cstdio>#include <cctype>#include <cstring>#include <sstream>#include <cstdlib>#include <iostream>#include <algorithm>#pragma comment(linker, "/STACK:102400000,102400000")using namespace std;#define   MAX           200005#define   MAXN          6005#define   maxnode       15#define   sigma_size    30#define   lson          l,m,rt<<1#define   rson          m+1,r,rt<<1|1#define   lrt           rt<<1#define   rrt           rt<<1|1#define   middle        int m=(r+l)>>1#define   LL            long long#define   ull           unsigned long long#define   mem(x,v)      memset(x,v,sizeof(x))#define   lowbit(x)     (x&-x)#define   pii           pair<int,int>#define   bits(a)       __builtin_popcount(a)#define   mk            make_pair#define   limit         10000//const int    prime = 999983;const int    INF   = 0x3f3f3f3f;const LL     INFF  = 0x3f3f;const double pi    = acos(-1.0);//const double inf   = 1e18;const double eps   = 1e-8;const LL    mod    = 1e9+7;const ull    mx    = 133333331;/*****************************************************/inline void RI(int &x) {    char c;    while((c=getchar())<'0' || c>'9');    x=c-'0';    while((c=getchar())>='0' && c<='9') x=(x<<3)+(x<<1)+c-'0'; }/*****************************************************/int dp[55][205];int a[55],b[55];int n,x,y;bool check(int m){    dp[0][0]=0;    for(int i=1;i<=x;i++) dp[0][i]=-1;    for(int i=1;i<=n;i++){        for(int j=0;j<=x;j++){            dp[i][j]=-1;            for(int k=0;k<=j;k++){                if(dp[i-1][k]!=-1&&a[i]*(j-k)<=m){                    dp[i][j]=max(dp[i][j],dp[i-1][k]+(m-a[i]*(j-k))/b[i]);                }            }        }    }    if(dp[n][x]>=y) return true;    return false;}int main(){    int t,kase=0;    cin>>t;    while(t--){        scanf("%d%d%d",&n,&x,&y);        kase++;        for(int i=1;i<=n;i++) scanf("%d%d",&a[i],&b[i]);        int l=1,r=400000;        while(l<=r){            int mid=(l+r)/2;            if(check(mid)) r=mid-1;            else l=mid+1;        }        printf("Case %d: ",kase);        cout<<l<<endl;    }    return 0;}
0 0
原创粉丝点击