 /**//*
題意:給出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
搜索
最新評論

|
|