 /**//*
题意:给出n个人,第i个人完成任务A需要Ai时间,任务B需要Bi时间
问完成x个A,y个B任务所需的最少时间 并行工作
脑残咯我,一开始就dp[i][j]=min(dp[i-1][j]+A[k],dp[i][j-1]+B[k])
能并行工作,上面式子当然不行,上面时间被累加了

二分时间T,在这个时间下,dp[n][x]表示前面n个人完成x个A任务还能继续完成的最大B任务数
然后背包就行了!

最后,发现这道题跟之前做的poj 1973一样的
再次醉了

背包是累加的!
*/
#include<cstdio>
#include<cstring>

const int MAXN = 201;
const int INF = 1000000000;

int n,x,y;
int dp[MAXN];
int A[MAXN],B[MAXN];

 inline int min(int a,int b) {return a<b?a:b;}
 inline int max(int a,int b) {return a>b?a:b;}

bool chk(int T)
  {
memset(dp,-1,sizeof(dp));
dp[0]=0;
for(int i=1;i<=n;i++)
 {
int k = min(x,T/A[i]);
if(dp[x]>=y)return true;//很重要的优化!!
for(int j=x;j>=0;j--)
for(int kk=0;kk<=k&&j-kk>=0;kk++)
 {
if(dp[j-kk]<0)continue;
dp[j]=max(dp[j],dp[j-kk]+(T-kk*A[i])/B[i]);
}
}
return dp[x]>=y;
}
int main()
  {
int T,t=1;
for(scanf("%d",&T);T--;)
 {
scanf("%d%d%d",&n,&x,&y);
for(int i=1;i<=n;i++)scanf("%d%d",&A[i],&B[i]);
int L=0,R=INF;
while(R-L>1)
 {
int M=(R+L)>>1;
if(chk(M))R=M;
else L=M;
}
printf("Case %d: %d\n",t++,R);
}
}
|
|
常用链接
随笔分类
Links
搜索
最新评论

|
|