题意:
有n个人,X个任务A,Y个任务B,
给出每个人做A做B的时间,一个人只能在某个时刻做一个工作,
有n个人,X个任务A,Y个任务B,
给出每个人做A做B的时间,一个人只能在某个时刻做一个工作,
问最短时间完成所有工作。
思路:
二分n个人用的时间,判断最优条件用DP。
可以二分就是因为时间越多的话肯定能做更多的task啊。
真的好神奇!n个人可以同一时间一起做事,那么对于给定的时间,也就是说每个人都拥有这么多时间,无非就是他会去怎么安排,那么就DP啊。
dp[i][j] 代表前 i 个人搞了 j 个A以后,还能搞多少个B;
判断一发就是个0/1背包,背包容量就是时间,枚举第i个人做A任务的数量 j ,那么B的数量 (time-a[i]*(j-k))/b[i];
//话说 对于求时间的问题,用二分搞的好多了!!!以后要想过去!!!DP最优解。
//突然发现对于二分这个搞法,真是每次想到都追悔莫及,瞎歪歪了一个点子:
//钱越多东西就可以买的越多;时间花的越多,事情就可以办的更多;the more...,the more...就可以用二分
#include<bits/stdc++.h>
using namespace std;
typedef __int64 LL;
int dp[210];
int a[60];
int b[60];
int n,X,Y;
bool DP(int time)
{
memset(dp,-1,sizeof(dp));
dp[0]=0;
for(int i=1;i<=n;i++)
{
for(int j=X;j>=0;j--)//枚举能够处理j个A
{
for(int k=j;k>=0;k--)
{
if(time>=(j-k)*a[i]&&dp[k]!=-1)
dp[j]=max(dp[j],dp[k]+(time-a[i]*(j-k))/b[i]);
}
}
if(dp[X]>=Y)
return true;
}
return false;
}
int main()
{
int T,cas=1;
scanf("%d",&T);
while(T--)
{
scanf("%d%d%d",&n,&X,&Y);
for(int i=1; i<=n; ++i)
scanf("%d%d",&a[i],&b[i]);
int left=0;
int right=600*1000;
while(left<right)
{
int mid=left+(right-left)/2;
if(DP(mid))
right=mid;
else
left=mid+1;
}
printf("Case %d: %d\n",cas++,left);
}
return 0;
}