[POJ1973]Software Company
题目大意:有两种工作需要N个工人完成,每种工作各有M份,而每个工人完成一份A工作、B工作各需要A[i],B[i]时间,求完成所有工作所需最少时间。
二分答案,用dp[i]表示完成i份A工作所能完成的最多B工作即可
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
#define N 120
#define INF -214748364
long test,n,m,a[N],b[N],i,j,k,t,v,low,high,dp[N][N];
int main(){
scanf("%d",&test);
while(test--){
scanf("%d%d",&n,&m);
j=0;
for(i=0;i<n;i++){
scanf("%d%d",&a[i],&b[i]);
j=max(j,a[i]);
j=max(j,b[i]);
}
high=(m*2/n+2)*j;
low=1;
while(low<high){
t=(low+high)>>1;
for(i=(t/a[0]);i>=0;i--) dp[0][i]=(t-i*a[0])/b[0];
for(i=(t/a[0])+1;i<=m;i++) dp[0][i]=INF;
for(i=1;i<n;i++){
for(j=0;j<=m;j++) dp[i][j]=dp[i-1][j];
for(k=(t/a[i]);k>=0;k--){
v=(t-(a[i]*k))/b[i];
for(j=k;j<=m;j++) dp[i][j]=max(dp[i][j],dp[i-1][j-k]+v);
}
}
if(dp[n-1][m]>=m) high=t;
else low=t+1;
}
printf("%d\n",low);
}
return 0;
}