/* 题目大意: 有x个A任务,y个B任务,n个人,第i个人完成一个A任务的时间为a[i], 完成一个B任务的时间为b[i],求:完成所有任务的最小时间? 注意: (1)两个人可以同时完成不同的任务 (2)也可以同时完成相同任务的不同子任务 主要算法: DP + Binary Search 过程: 首先用二分法定位时间 T 选定时间后使用DP计算时间是不是满足要求 满足要求后继续二分直到时间最少且满足要求。 dp[i][j] 表示前i个人完成j数量的A任务以后还能完成B任务的数量 dp[i][j+k] = max( dp[i][j+k] , dp[i-1][j]+min( T-k*a[i]/b[i] , y-dp[i-1][j] ) ); */ #include <iostream> #include <cstring> #include <cstdio> #include <string> using namespace std; #define maxn 52 #define maxm 202 int dp[maxn][maxm]; int a[maxn],b[maxn]; int x,y,n; int dpf(int T) { int i,j,k; for(i=0;i<maxn;i++) { for(j=0;j<maxm;j++) { dp[i][j] = -1; } } dp[0][0]=0; for(i=1;i<=n;i++) { for(j=0;j<=x;j++) { if(dp[i-1][j]!=-1) { for(k=0;k<=min(T/a[i],x-j);k++) { dp[i][j+k]=max(dp[i][j+k],dp[i-1][j]+min((T-k*a[i])/b[i],y-dp[i-1][j])); } } } } return dp[n][x]>=y; } int main() { int t; scanf("%d",&t); int count = 0,i; while(t--) { scanf("%d%d%d",&n,&x,&y); for(i=1;i<=n;i++) { scanf("%d%d",&a[i],&b[i]); } int l=0;int r=1000*200*2; int mid = (l+r)>>1; int ans; while(l<=r) { if(dpf(mid)) { r=mid-1; ans = mid; } else l=mid+1; mid = (l+r)>>1; } printf("Case %d: %d/n",++count,ans); } return 0; }