hdu3433A Task Process( 二分dp)

时间:2023-03-09 15:52:44
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-;
const double pi = acos(-1.0);
const double inf = ~0u>>;
int a[],b[];
int dp[][];
int main()
{
int n,i,j,t,x,y,g,kk=;
cin>>t;
while(t--)
{
scanf("%d%d%d",&n,&x,&y);
int minz = N;
for(i = ; i <= n ;i++)
{
scanf("%d%d",&a[i],&b[i]);
minz = min(minz,a[i]*x+b[i]*y);
}
int low = ,high = minz,mid;
while(low<=high)
{
mid = (low+high)>>;
memset(dp,-,sizeof(dp));
for(i = ; i <= x ; i++)
{
if(a[]*i<=mid)
dp[][i] = (mid-a[]*i)/b[];
}
for(i = ; i <= n ;i++)
{
for(j = ;j <= x ;j++)
for(g = ; g <= x-j ; g++)
{
if(mid<a[i]*j) break;
if(dp[i-][g]==-) break;
dp[i][j+g] = max(dp[i][j+g],(mid-a[i]*j)/b[i]+dp[i-][g]);
}
}
if(dp[n][x]>=y)
high = mid-;
else
low = mid+;
}
printf("Case %d: ",++kk);
cout<<low<<endl;
}
return ;
}