/**//* 题意:给出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
搜索
最新评论
|
|