hdu3433A Task Process( 二分dp)

链接

二分时间,在时间内dp[i][j]表示截止到第i个人已经做了j个A最多还能做多少个B

#include <iostream>

#include<cstdio>

#include<cstring>

#include<algorithm>

#include<stdlib.h>

#include<vector>

#include<cmath>

#include<queue>

#include<set>

using namespace std;

#define N 200000

#define LL long long

#define INF 0xfffffff

const double eps = 1e-8;

const double pi = acos(-1.0);

const double inf = ~0u>>2;

int a[55],b[55];

int dp[210][210];

int main()

{

    int n,i,j,t,x,y,g,kk=0;

    cin>>t;

    while(t--)

    {

        scanf("%d%d%d",&n,&x,&y);

        int minz = N;

        for(i = 1; i <= n ;i++)

        {

            scanf("%d%d",&a[i],&b[i]);

            minz = min(minz,a[i]*x+b[i]*y);

        }

        int low = 0,high = minz,mid;

        while(low<=high)

        {

            mid = (low+high)>>1;

            memset(dp,-1,sizeof(dp));

            for(i = 0 ; i <= x ; i++)

            {

                if(a[1]*i<=mid)

                dp[1][i] = (mid-a[1]*i)/b[1];

            }

            for(i = 2; i <= n ;i++)

            {

                for(j = 0 ;j <= x ;j++)

                    for(g = 0 ; g <= x-j ; g++)

                    {

                        if(mid<a[i]*j) break;

                        if(dp[i-1][g]==-1) break;

                        dp[i][j+g] = max(dp[i][j+g],(mid-a[i]*j)/b[i]+dp[i-1][g]);

                    }

            }

            if(dp[n][x]>=y)

            high = mid-1;

            else

            low = mid+1;

        }

        printf("Case %d: ",++kk);

        cout<<low<<endl;

    }

    return 0;

}
View Code

 

你可能感兴趣的:(process)