hdu3433A Task Process( 二分dp)
二分时间,在时间内dp[i][j]表示截止到第i个人已经做了j个A最多还能做多少个B
#include <iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<stdlib.h> #include<vector> #include<cmath> #include<queue> #include<set> using namespace std; #define N 200000 #define LL long long #define INF 0xfffffff const double eps = 1e-8; const double pi = acos(-1.0); const double inf = ~0u>>2; int a[55],b[55]; int dp[210][210]; int main() { int n,i,j,t,x,y,g,kk=0; cin>>t; while(t--) { scanf("%d%d%d",&n,&x,&y); int minz = N; for(i = 1; i <= n ;i++) { scanf("%d%d",&a[i],&b[i]); minz = min(minz,a[i]*x+b[i]*y); } int low = 0,high = minz,mid; while(low<=high) { mid = (low+high)>>1; memset(dp,-1,sizeof(dp)); for(i = 0 ; i <= x ; i++) { if(a[1]*i<=mid) dp[1][i] = (mid-a[1]*i)/b[1]; } for(i = 2; i <= n ;i++) { for(j = 0 ;j <= x ;j++) for(g = 0 ; g <= x-j ; g++) { if(mid<a[i]*j) break; if(dp[i-1][g]==-1) break; dp[i][j+g] = max(dp[i][j+g],(mid-a[i]*j)/b[i]+dp[i-1][g]); } } if(dp[n][x]>=y) high = mid-1; else low = mid+1; } printf("Case %d: ",++kk); cout<<low<<endl; } return 0; }